2010-09-27 42 views
1

我想在存儲過程幫助的TSQL語句中使用INT

@dealerids nvarchar(256) 

SELECT * 
FROM INVOICES as I 
WHERE convert(nvarchar(20), I.DealerID) in (@dealerids) 

I.DealerID創建以下SELECT語句是表中的INT。和dealerids的參數將被格式化,如 (8820,8881,8834)

當我使用提供的參數運行時,我沒有返回行。我知道這些發行商ID應該提供行,就好像我單獨做了一樣,但我得到了我期望的結果。 我認爲我在做

WHERE convert(nvarchar(20), I.DealerID) in (@dealerids) 

不正確。任何人都可以指出我在這裏做錯了嗎?

回答

2

不能使用@dealerids這樣,你需要使用動態SQL,像這樣:

@dealerids nvarchar(256) 

EXEC('SELECT * 
FROM INVOICES as I 
WHERE convert(nvarchar(20), I.DealerID) in (' + @dealerids + ')' 

的缺點是,你打開自己到SQL注入攻擊,除非你明確控制數據進入@dealerid s。

有更好的方法來處理這取決於您的SQL Server版本,它們記錄在this great article中。

+0

非常感謝,我將通讀這篇文章。我很欣賞這個方向! – twal 2010-09-27 18:41:34

2

拆分@dealerids到表中再加入

SELECT * 
FROM INVOICES as I 
JOIN 
ufnSplit(@dealerids) S ON I.DealerID = S.ParsedIntDealerID 

什錦split functions here(我大概一個數字表在這種情況下對於小串

+0

我試過了,它可以讓我創建存儲過程,但是當我運行它時,它會拋出這個期望:無效的對象名稱'ufnSplit。不幸的是這在SqlServer 2000 ..(我知道,他們需要得到一個新的版本!:)) – twal 2010-09-27 18:51:59

+0

@twal:閱讀鏈接,寫它。或者使用KM的答案。 – gbn 2010-09-27 18:52:38

+0

@twal,對於上面的代碼的工作,你需要創建一個函數** ufnSplit()**,它執行字符串操作並返回一個表。有很多鏈接顯示創建此功能的各種方法。 – 2010-09-27 19:24:26

4

使用表值參數(新的SQL Server 2008)設置它通過創建實際的表參數類型:

CREATE TYPE IntTableType AS TABLE (ID INTEGER PRIMARY KEY) 

你的程序將被:

Create Procedure up_TEST 
    @Ids IntTableType READONLY 
AS 

SELECT * 
    FROM ATable a 
    WHERE a.Id IN (SELECT ID FROM @Ids) 

RETURN 0 
GO 

如果您不能使用表值參數,請參閱:"Arrays and Lists in SQL Server 2005 and Beyond, When Table Value Parameters Do Not Cut it" by Erland Sommarskog,那麼在SQL Server中有很多方法來拆分字符串。本文涵蓋了幾乎所有方法的PRO和CON。一般來說,你需要創建一個分割函數。這是一個分裂的功能如何使用:

SELECT 
    * 
    FROM YourTable        y 
    INNER JOIN dbo.yourSplitFunction(@Parameter) s ON y.ID=s.Value 

I prefer the number table approach to split a string in TSQL但也有許多方法來拆分在SQL Server中的字符串,見前面的鏈接,這說明各的優點和缺點。

對於數字表的方法來工作,你需要做的這一次表的設置,這將創建一個包含從1到10000行的表Numbers

SELECT TOP 10000 IDENTITY(int,1,1) AS Number 
    INTO Numbers 
    FROM sys.objects s1 
    CROSS JOIN sys.objects s2 
ALTER TABLE Numbers ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number) 

一旦Numbers表格設置,創建此分割功能:

CREATE FUNCTION [dbo].[FN_ListToTable] 
(
    @SplitOn char(1)  --REQUIRED, the character to split the @List string on 
    ,@List  varchar(8000)--REQUIRED, the list to split apart 
) 
RETURNS TABLE 
AS 
RETURN 
(

    ---------------- 
    --SINGLE QUERY-- --this will not return empty rows 
    ---------------- 
    SELECT 
     ListValue 
     FROM (SELECT 
        LTRIM(RTRIM(SUBSTRING(List2, number+1, CHARINDEX(@SplitOn, List2, number+1)-number - 1))) AS ListValue 
        FROM (
          SELECT @SplitOn + @List + @SplitOn AS List2 
         ) AS dt 
         INNER JOIN Numbers n ON n.Number < LEN(dt.List2) 
        WHERE SUBSTRING(List2, number, 1) = @SplitOn 
      ) dt2 
     WHERE ListValue IS NOT NULL AND ListValue!='' 

); 
GO 

您現在可以輕鬆地拆分CSV字符串轉換成表格,並加入就可以了:

Create Procedure up_TEST 
@Ids VARCHAR(MAX) 
AS 
SELECT * FROM ATable a 
WHERE a.Id IN (SELECT ListValue FROM dbo.FN_ListToTable(',',@Ids))