2013-05-21 141 views
7

我的存儲過程中有一個nvarchar(MAX),它包含int值列表,我這樣做是因爲無法將int列表傳遞給我的存儲過程 , 但現在我得到問題,因爲我的數據類型是int,我想比較字符串列表。 有沒有辦法可以做到這一點?在SQL中將字符串列表轉換爲Int列表

---myquerry----where status in (@statuslist) 

但statuslist包含現在字符串值不是int,那麼如何將它們轉換爲INT?

更新:

USE [Database] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 


ALTER PROCEDURE [dbo].[SP] 
(
@FromDate datetime = 0, 
@ToDate datetime = 0, 
@ID int=0, 
@List nvarchar(MAX) //This is the List which has string ids// 
) 

AS SET FMTONLY OFF; DECLARE @sql爲nvarchar(MAX), @paramlist爲nvarchar(MAX)

SET @sql = 'SELECT ------ and Code in(@xList) 
    and -------------' 
SELECT @paramlist = '@xFromDate datetime,@xToDate datetime,@xId int,@xList nvarchar(MAX)' 

EXEC sp_executesql @sql, @paramlist, 
@xFromDate = @FromDate ,@[email protected],@[email protected],@[email protected] 
PRINT @sql 

所以,當我實現了功能分割,然後我不能指定字符內或分隔符,因爲它不接受它作爲(@list, '')。

(','+ @List +',')。

+0

那麼你可以寫一個表值函數分裂整型值的字符串或你可能如果使用表值參數你正在使用SQL Server 2008+(不真的與他們合作,所以不確定他們是否100%適合這個目的) –

+0

@尼爾:請詳細說明一下,你能否爲我提供一個相同的鏈接? –

+0

這篇文章顯示了我的意思:http://stackoverflow.com/questions/16040226/should-table-valued-parameters-be-used-here –

回答

8

可以使用XML參數向您的存儲過程發送一個int列表。這樣你就不必再解決這個問題了,這是一個更好,更乾淨的解決方案。

看看這個問題: Passing an array of parameters to a stored procedure

或檢查這個代碼項目:如果你堅持這樣做你的方式,你可以使用此功能 http://www.codeproject.com/Articles/20847/Passing-Arrays-in-SQL-Parameters-using-XML-Data-Ty

但是:

CREATE FUNCTION [dbo].[fnStringList2Table] 
(
    @List varchar(MAX) 
) 
RETURNS 
@ParsedList table 
(
    item int 
) 
AS 
BEGIN 
    DECLARE @item varchar(800), @Pos int 

    SET @List = LTRIM(RTRIM(@List))+ ',' 
    SET @Pos = CHARINDEX(',', @List, 1) 

    WHILE @Pos > 0 
    BEGIN 
     SET @item = LTRIM(RTRIM(LEFT(@List, @Pos - 1))) 
     IF @item <> '' 
     BEGIN 
      INSERT INTO @ParsedList (item) 
      VALUES (CAST(@item AS int)) 
     END 
     SET @List = RIGHT(@List, LEN(@List) - @Pos) 
     SET @Pos = CHARINDEX(',', @List, 1) 
    END 

    RETURN 
END 

這樣稱呼它:

SELECT  * 
FROM  Table 
WHERE status IN (SELECT * from fnStringList2Table(@statuslist)) 
+1

我喜歡XML解決方案,因爲它可以將更復雜的數據傳遞到proc中非常靈活,我喜歡您可以將XML數據視爲一張桌子。 –

+0

這是一個內聯函數? –

+0

這不起作用,因爲我使用的是動態sql,並且''正在創建錯誤 –

0

其實,你可以通過創建User Defined Table Type發送int值的列表,你的程序。但是,這意味着需要更多的工作來填充表參數。

在你的情況,你可以使用sp_executesql存儲過程來實現你想要的是這樣的:

declare @statement nvarchar(4000) = '----your query---- where status in (' 
+ @statusList +')' 
sp_executesql @statement 
+0

我想用上面的,創建用戶定義的表,你能告訴我如何做到這一點? –

+0

@ItiTyagi,請看看這裏http://technet.microsoft.com/en-us/library/ms175007(v=sql.100).aspx和這裏http://technet.microsoft.com/en-us /library/bb510489(v=sql.100).aspx。第二個鏈接有關如何使用存儲過程的自定義類型的示例。 – RePierre

+0

我也更新了我的代碼,我希望你可以幫助我。 –

0

您可以通過使用SQL函數將返回一個整數數組做.. 會如果您將@Delimiter分隔的字符串傳遞給您的存儲過程,那麼以後可以正確處理它們會很棒。

寫一個函數將數據作爲@Delimiter這裏分裂如下

ALTER FUNCTION [YourSchema].[SplitValues] (@StringArray NVARCHAR(MAX), @Delimiter NVARCHAR(10)) 
RETURNS @ResultedValues table 
(
ResultValue INT 
) 
AS 
BEGIN 
    WHILE (CHARINDEX(@Delimiter,@StringArray)>0) 
    BEGIN 
    INSERT INTO @Tokens (Token) VALUES (LTRIM(RTRIM(SUBSTRING(@StringArray,1,CHARINDEX(@Delimiter,@StringArray)-1)))) 
    SET @String = SUBSTRING(@StringArray, 
    CHARINDEX(@Delimiter,@StringArray)+LEN(@Delimiter),LEN(@StringArray)) 
    END 
INSERT INTO @ResultedValues (ResultValue) VALUES (CAST(LTRIM(RTRIM(@String)) AS INT)) 
RETURN 
END 

,然後用它像下面,我使用(,)

SELECT ResultValue [YourSchema].[SplitValues](@statuslist,',') 
+0

這我已經使用,但它並沒有幫助我,我無法使用「」因爲它顯示的錯誤在我的動態SQL –

7

你可以用字符串列表工作太。我經常做。

declare @statuslist nvarchar(max) 
set @statuslist = '1, 2, 3, 4' 

declare @sql nvarchar(max) 
set @sql = 'select * from table where Status in (' + @statuslist + ')' 
Execute(@sql) 
+0

沒有它給我一個錯誤,必須聲明它作爲一個標量型等 –

+0

聲明你的SQL變量爲nvarchar,並傳遞一個逗號分隔格式的字符串參數。它可能會工作。 – Azade

+0

仍然不工作,因爲我有一個動態的SQL,並且當我使用'''sql'select --------' –

0

這裏是和如何做到這一點的例子中,Link更多信息

ALTER FUNCTION iter_intlist_to_tbl (@list nvarchar(MAX)) 
    RETURNS @tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL, 
         number int NOT NULL) AS 


BEGIN 

    DECLARE @startpos int, 
      @endpos int, 
      @textpos int, 
      @chunklen smallint, 
      @str  nvarchar(4000), 
      @tmpstr nvarchar(4000), 
      @leftover nvarchar(4000) 


    SET @textpos = 1 
    SET @leftover = '' 


    WHILE @textpos <= datalength(@list)/2 
    BEGIN 


     SET @chunklen = 4000 - datalength(@leftover)/2 


     SET @tmpstr = ltrim(@leftover + substring(@list, @textpos, @chunklen)) 

     SET @textpos = @textpos + @chunklen 

     SET @startpos = 0 

     SET @endpos = charindex(' ' COLLATE Slovenian_BIN2, @tmpstr) 

     WHILE @endpos > 0 
     BEGIN 

      SET @str = substring(@tmpstr, @startpos + 1, @endpos - @startpos - 1) 

      IF @str <> '' 
       INSERT @tbl (number) VALUES(convert(int, @str)) 

      SET @startpos = @endpos 

      SET @endpos = charindex(' ' COLLATE Slovenian_BIN2, @tmpstr, @startpos + 1) 
     END 

     SET @leftover = right(@tmpstr, datalength(@tmpstr)/2 - @startpos) 
    END 

    IF ltrim(rtrim(@leftover)) <> '' 
     INSERT @tbl (number) VALUES(convert(int, @leftover)) 

    RETURN 
END 


-- ############################ Example ############################ 
--CREATE PROCEDURE get_product_names_iter @ids varchar(50) AS 
--SELECT P.ProductName, P.ProductID 
--FROM  Northwind..Products P 
--JOIN  iter_intlist_to_tbl(@ids) i ON P.ProductID = i.number 
--go 
--EXEC get_product_names_iter '9 12 27 37' 
-- ############################ WICHTIG ############################