iT邦幫忙

DAY 12
7

T-SQL 應用之美系列 第 12

使用流程控制:IF...ELSE

不管哪一種語言都具備流程控制的功能,用來控制程式執行與流程的流向,透過流程控制可以讓程式更容易維護。
這次要討論根據特定條件來執行不同流程的指令:IF...ELSE。
很多人都以為 IF 後面一定要跟著 ELSE 子句,其實是可以不用的。例如,在建立資料表之前,通常都會檢查是否已經存在相同名稱的資料表:

-- 檢查資料表是否已經存在,如果存在,就把它刪除掉
IF OBJECT_ID(N'myTable', N'U') IS NOT NULL
	DROP TABLE myTable

通常我們會使用代碼來儲存資料,例如在性別欄位中,使用 M 代表男性,使用 F 代表女性。而在顯示這類欄位的資料時,就可以使用 IF...ELSE 來將代碼轉換成文字描述,這樣才能讓然人家清楚的知道資料所代表的意義是什麼:

USE AdventureWorks
GO

-- 定義變數
DECLARE @EmployeeID int, @Gender nchar(1), @ChineseGender nchar(2)

-- 定義 CURSOR
DECLARE myCursor CURSOR FOR
	SELECT EmployeeID, Gender FROM HumanResources.Employee

-- 開啟 CURSOR
OPEN myCursor

-- 抓出資料
FETCH NEXT FROM myCursor
	INTO @EmployeeID, @Gender

-- 檢查 @@FETCH_STATUS 來決定是否要繼續執行
WHILE (@@FETCH_STATUS = 0)
	BEGIN
		PRINT N'員工編號:' + CAST(@EmployeeID AS NCHAR(10))
		
		IF @Gender = 'M'
			SET @ChineseGender = N'男'
		ELSE
			SET @ChineseGender = N'女'
		
		PRINT N'性別:' + @ChineseGender
		PRINT REPLICATE('-', 20)

		FETCH NEXT FROM myCursor
			INTO @EmployeeID, @Gender
	END

-- 關閉 CURSOR
CLOSE myCursor

-- 釋放 CURSOR
DEALLOCATE myCursor

執行的部分結果如下:

最後我們討論使用 IF...ELSE 跟資料庫效能的一個重要議題。
假設資料表中,當某個欄位的欄位值已經存在資料,就要更新這些資料,如果沒有相關的資料存在,就要新增一筆資料。通常我們會直覺的使用下面這種寫法:

-- 計算筆數
IF (SELECT COUNT(*) FROM myTable WHERE 欄位名稱='欄位值') > 0
    UPDATE myTable SET (...) WHERE 欄位名稱='欄位值'
ELSE
    INSERT INTO myTable VALUES (...)

因為我們只是要檢查是否存在任何相符的記錄,根本不需要知道有多少筆資料,所以應該改用 IF EXISTS 來取代 SELECT COUNT(*)。這麼一來,只要找到第一筆相符的資料時,IF EXISTS 就會馬上停止搜尋,也就是說,根本不需要再多花費其他額外的時間,就已經知道至少存在一筆相符的資料了。所以應該要將程式碼改寫成下面這樣:

-- 檢查資料是否已經存在
IF EXISTS (SELECT * FROM myTable WHERE 欄位名稱='欄位值')
    UPDATE myTable SET (...) WHERE 欄位名稱='欄位值'
ELSE
    INSERT INTO myTable VALUES (...)

但是上面那種寫法並不是最好的方法,因為在執行 SELECT 或 UPDATE 指令時,都會進行 Table Scan 或 Index Scan,也就是說最多會進行 2 次 SCAN,最少 1 次 SCAN。在改用下面的寫法之後,可以確保最多只會執行 1 次 Table Scan 或 Index Scan:

-- 更新資料表
UPDATE myTable SET (...) WHERE 欄位名稱='欄位值'

-- 檢查更新的資料筆數是否為 0,是 0 的話,就表示根本沒相符的資料要更新
-- 所以要新增一筆新的資料
IF @@ROWCOUNT = 0
    INSERT INTO myTable VALUES (...)

上一篇
使用流程控制:WHILE、BREAK 與 CONTINUE
下一篇
使用流程控制:CASE...WHEN
系列文
T-SQL 應用之美30

尚未有邦友留言

立即登入留言