使用CASE表示式替代SQL Server中的動態SQL
翻譯自:
問題:
在決定IF/ELSE時,會有很多UPDATE查詢,某些情況下我使用遊標,但迴圈幾千行資料的UPDATE時,會花費非常多的事件。我也使用一些動態SQL來處理一些查詢引數。除此之外,還有更好的選擇嗎?
解決方案:
CASE表示式是在解決SQLServer查詢問題上的一個強大的工具。你可能感覺到它在SELECT語句中的用法類似於IF/ELSE的處理。但是,相對與IF/ELSE,CASE表示式卻沒有那麼多限制。
在以下程式碼中將展示CASE表示式的用處:
l 消除在UPDATE行時的遊標迴圈。
l 在使用聚集函式時,執行特殊處理。
l 不使用動態SQL的動態ORDER BY 和WHERE子句
讓我們看看以下例子:
首先,先建立一個名為Customer的表並插入資料:
CREATE TABLE dbo.Customer
(
customerid INT IDENTITY PRIMARY KEY,
firstname VARCHAR(40) NOT NULL,
lastname VARCHAR(40) NOT NULL,
statecode VARCHAR(2) NOT NULL,
totalsales money NOT NULL DEFAULT 0.00
)
INSERT INTO dbo.Customer(firstname, lastname, statecode, totalsales)
SELECT 'Thomas', 'Jefferson', 'VA', 100.00
INSERT INTO dbo.Customer(firstname, lastname, statecode, totalsales)
SELECT 'John', 'Adams', 'MA', 200.00
INSERT INTO dbo.Customer(firstname, lastname, statecode, totalsales)
SELECT 'Paul', 'Revere', 'MA', 300.00
INSERT INTO dbo.Customer(firstname, lastname, statecode, totalsales)
SELECT 'Ben', 'Franklin', 'PA', 400.00
GO
示例1:
由於報表展示的需要,在一個非正規化化的表中增加一個所在州描述列。現在,你可以使用遊標和來迴圈更新每一行。但是遊標往往是效能殺手。你也可以使用大量UPDATE語句,但是這將導致程式非常臃腫。
對此,可以在一個UDPATE語句的SET 子句中使用帶有CASE關鍵字來實現更有效的操作:
ALTER TABLE dbo.Customer ADD statedescription VARCHAR(50) NULL
GO
UPDATE dbo.Customer
SET stateDescription = CASE WHEN statecode = 'MA' THEN 'Massachusetts'
WHEN statecode = 'VA' THEN 'Virginia'
WHEN statecode = 'PA' THEN 'Pennsylvania'
ELSE NULL
END
示例2:
當我們需要統計所有來自Massachusetts州使用者的數量及他們的平均總消費時。我們能限制查詢在僅僅是Massachusetts的客戶。但這將使得在得到使用者總數時語句變得臃腫,為此,可以在聚集函式中使用CASE表示式來得到特定資訊:
SELECT COUNT(*) AS TotalCustomers,
SUM(CASE WHEN statecode = 'MA' THEN 1 ELSE NULL END) AS TotalMassCustomers,
AVG(CASE WHEN statecode = 'MA' THEN totalsales ELSE NULL END) AS TotalMassSales
FROM dbo.Customer
因為在聚集函式中,NULL值不參與計算,所以可以通過這個特性來獲得我們想要的資料。
示例3:
第三個案例來自於我們的桌面,我們需要一個儲存過程來被應用程式呼叫,但使用者想根據第一個名字或者第二個名字排序。其中一個方法是使用動態SQL來解決這個問題,但是我們可以使用CASE來等價實現:
CREATE PROCEDURE dbo.getCustomerData @sortbyVARCHAR(9), @sortdirection CHAR(4)
AS
SET nocount ON
SELECT customerid, firstname, lastname, statecode, statedescription, totalsales
FROM dbo.Customer
ORDER BY
CASE @sortdirection
WHEN 'asc' THEN
CASE @sortby
WHEN 'firstname' THEN firstname
WHEN 'lastname' THEN lastname
END
END
ASC,
CASE @sortdirection
WHEN 'desc' THEN
CASE @sortby
WHEN 'firstname' THEN firstname
WHEN 'lastname' THEN lastname
END
END
DESC
GO
EXEC dbo.getCustomerData'lastname', 'desc'
示例4:
最後一個例子中與示例3相似,我們需要改動儲存過程去查詢特定州的客戶,如果該引數被忽略,則返回所有客戶的所在州。
ALTER PROCEDURE dbo.getCustomerData @sortby VARCHAR(9), @sortdirection CHAR(4), @statecode VARCHAR(2) = NULL
AS
SET nocount ON
SELECT customerid, firstname, lastname, statecode, statedescription, totalsales
FROM dbo.Customer
WHERE statecode = CASE WHEN @statecode IS NOT NULL THEN @statecode
ELSE statecode
END
ORDER BY
CASE @sortdirection
WHEN 'asc' THEN
CASE @sortby
WHEN 'firstname' THEN firstname
WHEN 'lastname' THEN lastname
END
END
ASC,
CASE @sortdirection
WHEN 'desc' THEN
CASE @sortby
WHEN 'firstname' THEN firstname
WHEN 'lastname' THEN lastname
END
END
DESC
GO
EXEC dbo.getCustomerData 'lastname', 'desc', 'MA'
相關文章
- SQL CASE 表示式SQL
- 瞭解GaussDB SQL中CASE表示式SQL
- 神奇的 SQL 之 CASE表示式,妙用多多 !SQL
- GaussDB SQL基本語法示例-CASE表示式SQL
- SQL Server CASE WHEN ... THEN ... ELSE ... ENDSQLServer
- sql server 使用SQLServer
- SQL正規表示式SQL
- SQL Server 2008中Analysis Services的新特性——深入SQL Server 2008SQLServer
- MaxCompute SQL 使用正規表示式選列SQL
- sql裡的正規表示式SQL
- 帶你瞭解GaussDB SQL中的BOOLEAN表示式SQLBoolean
- SQL Server 2016 函式:CASTSQLServer函式AST
- SQL Server常用函式整理SQLServer函式
- .sql檔案匯入到sql server中SQLServer
- SQL Server 中的 ACID 屬性SQLServer
- SQL Server中row_number函式的常見用法SQLServer函式
- 【SQL】SQL中if條件的使用SQL
- SQL Server建立使用者函式與應用SQLServer函式
- sql serverSQLServer
- MyBatis 動態 SQLMyBatisSQL
- MybBatis動態SQLBATSQL
- Mybatics動態sqlBATSQL
- mybatis動態SQLMyBatisSQL
- Sql Server資料庫類似正規表示式的字元處理問題SQLServer資料庫字元
- SQL Server中GROUP BY(連結)SQLServer
- 【Case】SQL SERVER 屬性OWNER不可用於資料庫xxx。SQLServer資料庫
- sql case when, Exist ,group by ,聚合SQL
- Oracle case when改寫SQLOracleSQL
- SQL中的替換函式replace()使用SQL函式
- Sql中SYSDATE函式的使用方法SQL函式
- SQL Server 中的一些概念SQLServer
- SQL Server中的版本號如何理解SQLServer
- SQL中的case when then else end用法 【詳細】轉載SQL
- SQL server儲存過程函式SQLServer儲存過程函式
- 【SQL Server】常見系統函式SQLServer函式
- ORACLE中使用SQL的正規表示式判斷郵箱格式OracleSQL
- 使用sql Server自帶之sql Mail派信須知SQLServerAI
- Blazor使用sql server 資料庫BlazorSQLServer資料庫
- SQL 獲取SQL Server中兩個日期之間的所有日期SQLServer