2013年10月5日 星期六

查詢若具有部門代碼時,則列出該部門員工,若無則為全部

當查詢條件中明確指出特定部門代碼,則列出該部門之員工資料,若無則查詢出所有員工資料,本範例重點在於CASE WHENOR邏輯判斷式之應用,將以僅以MSSQL為例,撰寫Stored Procedure以進行測試,如下。
部門
SQL
執行結果
說明
全部
EXEC ListEmp ''


部門代碼參數為空時,代表列出所有員工資料。
IT部門
EXEC ListEmp 'IT'

部門代碼為指定部門時(ex:IT),則列出該員工資料。

ListEmp程式碼(MSSQL
SQL
說明
CREATE PROCEDURE ListEmp
(
@Dept_No varchar(10)
)
AS
BEGIN
SELECT *
FROM Emp
WHERE 1=1
      AND (1 = CASE WHEN @Dept_No='' THEN 1 ELSE 0 END --重點1, CASE WHEN
           OR DEPT_NO =@Dept_No                          --重點2, OR
          )
END
SP是應用SELECT敍述句進行查詢,並直接將結果傳回,為MSSQL中相當獨特且簡便之作法。

此語法開發上雖簡便,但應用上則有所限制,難以搭配其他查詢語法使用,2005以上版本建議改用FUNCTION,結果是以TABLE方式傳回。

將條件式整理如下表(重點1
#
條件式
ALL
IT
說明
1
1 = CASE WHEN @Dept_No='' THEN 1 ELSE 0 END
1
0
當部門代碼為空時,CASE WHEN運算結果為11=1成立;指定部門時則1=0不成立
2
DEPT_NO =@Dept_No
0
1
當部門代碼為空時,條件不成立。
部門代碼不為空時,條件成立。
OR

1
1
OR運算特性,任何條件成立則此運算成立。
#1(即1=1)成立,則不論#2結果,均成立。
#1(即1=0)不成立,但#2成立,仍成立。
再將2個條件式以OR進行判斷,不管是全部或IT部門均有其中一個條件成立(重點2)。

對於此範例,大部分作法會將兩種情況撰寫成2段類似之SQL,以IF…ELSE進行判斷、或以UNION ALL方式將兩段結合,或者Dynamic SQL動態組合查詢語法並執行。前述常用方法,SQL將變得非常龐大,邏輯或查詢欄位異動時需同時變更兩段增加維護成本,可使用CASE WHEN判斷查詢類型,以促使(enable)或取消(disable)另一查詢條件是否使用。應用此方法可以大幅縮減SQL複雜度(行數),不管ORACLEMSSQL均可使用。

測試資料(以MSSQL 2008Values方法建立)
SELECT * INTO Emp
FROM (VALUES ('A01', '麥坤',  '200', 'IT')
           , ('A02', '拖線',  '201', 'IT')
           , ('A03', '邁爵士', '901', 'MA')
           , ('A04', '郝莉莉', '801', 'MK')
      ) AS EMP(EMP_NO, EMP_NAME, EXT, DEPT_NO)


沒有留言:

張貼留言