首页 文章

在SQL中将字符串列表转换为Int列表

提问于
浏览
8

我的存储过程中有一个nvarchar(MAX),其中包含int值列表,我这样做 it is not possible to pass int list to my stored procedure ,但是,现在我遇到问题,因为我的数据类型是int,我想比较字符串列表 . 有没有办法可以做同样的事情?

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

但是statuslist现在包含字符串值而不是int,那么如何将它们转换为INT?

UPDate:

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 ,@xToDate=@ToDate,@xId=@ID,@xList=@List
PRINT @sql

因此,当我实现拆分的函数时,我无法指定字符或分隔符,因为它不接受它作为 (@List,',').

(','+@List+',').

5 回答

  • 7

    可以使用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))
    
  • 10

    您也可以使用字符串列表 . 我经常做 .

    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

    实际上,您 can 通过创建 User Defined Table Typeint 值列表发送到您的过程 . 但是,这意味着需要更多工作才能填充表参数 .

    在您的情况下,您可以使用sp_executesql存储过程来实现您想要的内容:

    declare @statement nvarchar(4000) = '----your query---- where status in (' 
    + @statusList +')'
    sp_executesql @statement
    
  • 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 ############################
    
  • 0

    您可以通过使用sql函数来执行此操作,该函数将返回一个整数数组 . 如果您将@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
    

    然后像下面这样使用它,我在这里使用(,)作为@Delimiter

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

相关问题