2012-02-03

T-SQL WHERE IN 變數 有多筆值查無資料錯誤

在撰寫Stored Procedure時,發現在where條件中若以宣告的變數篩選資料,
當變數為多筆值並搭配WHERE IN的時候會發生查詢不到資料的情況
DECLARE @xTmp VarCHAR(100)

SET @xTmp = 'A01,B01,B99'

select GPNa,DTNo,DTNa
from NOM
where GPNo='SO'
and DTNo in (@xTmp)

GPNa       DTNo           DTNa
---------- -------------- ----------------

(0 個資料列受到影響)
此時需自行新增一個切割字串放入暫存Table的Function來解決此問題
USE [DATABASENAME]

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FN_SplitStr]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[FN_SplitStr]

USE [DATABASENAME]
GO

CREATE FUNCTION [dbo].[FN_SplitStr](@xStr NVarchar(MAX),@xFStr varchar(1))
                RETURNS @TmpTable TABLE ( TmpStr NVarchar(MAX))
AS
BEGIN
    --@xStr 欲切割字串
    --@xFStr 切割用判定字元
    --@TmpTable 存放切割後資料

    DECLARE @xTmpStr NVarchar(MAX)--暫存字串

    SET @xStr = @xStr + @xFStr--分割字串最後加上一個分割字元
    SET @xTmpStr = ''--清空暫存字串
    WHILE CHARINDEX(@xFStr,@xStr)>0--判斷是否有分割字元存在
    BEGIN
        --SET @xTmpStr = @xTmpStr + SUBSTRING(@xStr,1,CHARINDEX(@xFStr,@xStr)-1)
        SET @xTmpStr = SUBSTRING(@xStr,1,CHARINDEX(@xFStr,@xStr)-1)
        IF Replace(@xTmpStr,' ','') <> ''--不為空值才寫入@TmpTable
            INSERT INTO @TmpTable (TmpStr) values (@xTmpStr)        SET @xStr = SUBSTRING(@xStr,CHARINDEX(@xFStr,@xStr)+1,LEN(@xStr))
    END

    RETURN
END
DECLARE @xTmp VarCHAR(100)
SET @xTmp = 'A01,B01,B99'

select GPNa,DTNo,DTNa
from NOM
where GPNo='SO'
and DTNo in (select * from dbo.FN_SplitStr(@xTmp,','))

GPNa       DTNo           DTNa
---------- -------------- ----------------
成品出入庫類別    A01     生產入庫
成品出入庫類別    B01     銷貨出庫
成品出入庫類別    B99     其他出庫

(3 個資料列受到影響)

參考自
[TSQL]Procdure 或 SqlParameter 來下SQL指令 Where In 多個值的變數解決方法
在T-SQL進行字串分割
張貼留言