58

私が次のものを持っているとしましょう:

DECLARE @ExcludedList VARCHAR(MAX)

SET @ExcludedList = 3 + ', ' + 4 + ' ,' + '22'

SELECT * FROM A WHERE Id NOT IN (@ExcludedList)

エラー : varchar 値 ', ' をデータ型 int に変換するときに変換に失敗しました。

エラーの原因はわかったのですが、解決方法がわかりません...

4

8 に答える 8

53

これは、テーブル変数を使用して IN 句に複数の値をリストする例です。明らかな理由は、長い手順の中で値のリストを 1 か所だけ変更できるようにするためです。

さらに動的にしてユーザー入力を許可するには、入力用の varchar 変数を宣言し、WHILE を使用して変数内のデータをループ処理し、テーブル変数に挿入することをお勧めします。

@your_list、Your_table、および値を実際のものに置き換えます。

DECLARE @your_list TABLE (list varchar(25)) 
INSERT into @your_list
VALUES ('value1'),('value2376')

SELECT *  
FROM your_table 
WHERE your_column in ( select list from @your_list )

上記の select ステートメントは、次と同じことを行います。

SELECT *  
FROM your_table 
WHERE your_column in ('value','value2376' )
于 2014-12-11T12:46:24.187 に答える
45

これを動的spのように実行する必要があります

DECLARE @ExcludedList VARCHAR(MAX)

SET @ExcludedList = '3,4,22,6014'
declare @sql nvarchar(Max)

Set @sql='SELECT * FROM [A] WHERE Id NOT IN ('+@ExcludedList+')'

exec sp_executesql @sql
于 2010-05-31T15:51:47.480 に答える
20
DECLARE @IDQuery VARCHAR(MAX)
SET @IDQuery = 'SELECT ID FROM SomeTable WHERE Condition=Something'
DECLARE @ExcludedList TABLE(ID VARCHAR(MAX))
INSERT INTO @ExcludedList EXEC(@IDQuery)    
SELECT * FROM A WHERE Id NOT IN (@ExcludedList)

古い投稿に返信していることは知っていますが、動的SQLの使用を避けたい場合に変数テーブルを使用する方法の例を共有したいと思いました。それが最も効率的な方法かどうかはわかりませんが、動的SQLがオプションでなかったとき、これは過去に私にとってはうまくいきました。

于 2011-10-18T19:59:18.933 に答える
9

IN句で変数を使用することはできません。動的 SQLを使用するか、関数 (TSQL または CLR) を使用して値のリストをテーブルに変換する必要があります。

動的 SQL の例:

DECLARE @ExcludedList VARCHAR(MAX)
    SET @ExcludedList = 3 + ',' + 4 + ',' + '22'

DECLARE @SQL NVARCHAR(4000)
    SET @SQL = 'SELECT * FROM A WHERE Id NOT IN (@ExcludedList) '

 BEGIN

   EXEC sp_executesql @SQL '@ExcludedList VARCHAR(MAX)' @ExcludedList

 END
于 2010-05-31T15:48:20.903 に答える
6

まず、次のように、区切られた値のリストをテーブルに分割するクイック関数を作成します。

CREATE FUNCTION dbo.udf_SplitVariable
(
    @List varchar(8000),
    @SplitOn varchar(5) = ','
)

RETURNS @RtnValue TABLE
(
    Id INT IDENTITY(1,1),
    Value VARCHAR(8000)
)

AS
BEGIN

--Account for ticks
SET @List = (REPLACE(@List, '''', ''))

--Account for 'emptynull'
IF LTRIM(RTRIM(@List)) = 'emptynull'
BEGIN
    SET @List = ''
END

--Loop through all of the items in the string and add records for each item
WHILE (CHARINDEX(@SplitOn,@List)>0)
BEGIN

    INSERT INTO @RtnValue (value)
    SELECT Value = LTRIM(RTRIM(SUBSTRING(@List, 1, CHARINDEX(@SplitOn, @List)-1)))  

    SET @List = SUBSTRING(@List, CHARINDEX(@SplitOn,@List) + LEN(@SplitOn), LEN(@List))

END

INSERT INTO @RtnValue (Value)
SELECT Value = LTRIM(RTRIM(@List))

RETURN

END 

次に、このように関数を呼び出します...

SELECT * 
FROM A
LEFT OUTER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value
WHERE f.Id IS NULL

これは私たちのプロジェクトで本当にうまくいきました...

もちろん、その場合は逆のこともできます(ただし、あなたの質問ではありません)。

SELECT * 
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value

これは、オプションの複数選択パラメーター リストを持つレポートを扱うときに非常に便利です。パラメータが NULL の場合は、すべての値を選択する必要がありますが、1 つ以上の値がある場合は、それらの値でレポート データをフィルタリングする必要があります。次に、次のように SQL を使用します。

SELECT * 
FROM A
INNER JOIN udf_SplitVariable(@ExcludedList, ',') f ON A.Id = f.Value OR @ExcludeList IS NULL

このように、@ExcludeList が NULL 値の場合、結合の OR 句は、この値のフィルタリングをオフにするスイッチになります。とても便利な...

于 2014-08-29T17:22:19.377 に答える
1

問題は

3 + ', ' + 4

に変更します

'3' + ', ' + '4'

DECLARE @ExcludedList VARCHAR(MAX)

SET @ExcludedList = '3' + ', ' + '4' + ' ,' + '22'

SELECT * FROM A WHERE Id NOT IN (@ExcludedList)

クエリが次のようになるように SET @ExcludedListe

また

SELECT * FROM A WHERE Id NOT IN ('3', '4', '22')

また

SELECT * FROM A WHERE Id NOT IN (3, 4, 22)
于 2010-05-31T15:36:28.363 に答える
1

これを試して:

CREATE PROCEDURE MyProc @excludedlist integer_list_tbltype READONLY AS
  SELECT * FROM A WHERE ID NOT IN (@excludedlist)

そして、次のように呼び出します。

DECLARE @ExcludedList integer_list_tbltype
INSERT @ExcludedList(n) VALUES(3, 4, 22)
exec MyProc @ExcludedList
于 2010-05-31T15:47:15.527 に答える
1

動的クエリなしでそれを行う別の解決策があります。xquery の助けを借りてそれを行うこともできます。

    SET @Xml = cast(('<A>'+replace('3,4,22,6014',',' ,'</A><A>')+'</A>') AS XML)
    Select @Xml

    SELECT A.value('.', 'varchar(max)') as [Column] FROM @Xml.nodes('A') AS FN(A)

完全な解決策は次のとおりです

于 2011-12-21T20:13:21.687 に答える