2013-05-21 135 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 ############################