9

ストアド プロシージャに int 値のリストを含む nvarchar(MAX) があります。ストアド プロシージャにint list を渡すことができないため、このようにしましたが、データ型が int であるため問題が発生しています。文字列のリストを比較したい。私が同じことをする方法はありますか?

---myquerry----where status in (@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 ,@xToDate=@ToDate,@xId=@ID,@xList=@List
PRINT @sql

そのため、分割する関数を実装すると、 (@List,',')として受け入れられないため、文字または区切り文字を指定できません。

または(','+@List+',')。

4

6 に答える 6

14

XML パラメータを使用してint リストをストアド プロシージャに送信できます。これにより、この問題に取り組む必要がなくなり、より優れたよりクリーンなソリューションになります。

この質問を見てください: パラメータの配列をストアド プロシージャに渡す

または、このコード プロジェクトを確認してください: 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))
于 2013-05-21T07:29:38.030 に答える
9

文字列リストも操作できます。いつもしています。

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)
于 2013-05-21T07:25:54.883 に答える
2

これは、整数配列を返す sql 関数を使用して行うことができます。 @Delimiter で区切られた文字列をストアド プロシージャに渡して、後で適切に処理できると便利です。

次のように、データを分割する関数を 1 つ記述します。

CREATE FUNCTION [dbo].[SplitValues] (@StringArray NVARCHAR(MAX), @Delimiter NVARCHAR(10)) 
RETURNS @ResultedValues table 
(
ResultValue INT
) 
AS 
BEGIN       
  DECLARE @Tokens TABLE(Token nvarchar)         
  DECLARE   @String nvarchar

  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,',')
于 2013-05-21T07:19:56.507 に答える
0

ここにそれを行う方法の例と詳細情報へのリンクがあります

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 ############################
于 2013-05-21T07:35:05.690 に答える