2017-03-17 10 views
0

ダイナミック検索ストアドプロシージャで何か助けてもらえますか?SQL Serverストアドプロシージャの惨事

これは私のストアドプロシージャです:

DECLARE mycursorForCountry CURSOR FOR 
    SELECT CountryNames 
    FROM [Countries].[dbo].[World] 
    WHERE UserID = @userID 

    OPEN mycursorForCountry 

    FETCH NEXT FROM mycursorForCountry INTO @CountryNames 

    WHILE (@@FETCH_STATUS = 0) 
    BEGIN 
     INSERT INTO @CountryTbl 
      SELECT DISTCINT * 
      FROM ufn_Split((@CountryNames),',') 

     FETCH NEXT FROM mycursorForCountry INTO @CountryNames 
    END 

    CLOSE mycursorForCountry 
    DEALLOCATE mycursorForCountry 

    DECLARE @SQL nvarchar(MAX) 
    SET @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE Country_Name IN('[email protected]+')' 

    EXEC sp_executesql @SQL 

私はエラーを取得しています:

Msg 102, Level 15, State 1, Line 260
Incorrect syntax near 'AFRICA'

+0

:それはカーソルを使用しません。また、テーブル@CountryTblを使用しないことに注意してください?あなたはクエリの '@ CountryNames'を渡すことができます。 – Shaharyar

+0

@Shaharyarこれは私のクエリの他の部分を持っているので、私のコードの一部です – Clifford

+0

@CountryNames値のサンプルを教えてもらえますか? – Hadi

答えて

2
ライン

set @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE 
    Country_Name IN('[email protected]+')' 

@CountryNamesによって返された値をラップしていません一重引用符で囲みます。あなたは動的SQL文をプリントアウトし、このようにしてSQL文を作成しているとき

set @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE 
    Country_Name IN('''[email protected]+''')' 
    --    ^-------------------^------- added two single-quotes 

提案

:(2つの単一引用符を使用すると、単一の単一引用符にそれをエスケープ)を次のように変更そのような場合のトラブルシューティングのために、デバッグの目的でprint @SQLを使用してください。あなたがそうしたい場合は、@SQLの内容は、以下の不正なクエリだった気づいていると思います:

SELECT * FROM [Information].[dbo].[Media] WHERE Country_Name IN (AFRICA) 

あなたがに包まれていなかったIN文の中で文字列を持っていたことをあなたに示さなければならないこと引用符。


EDIT:正しく国のカンマ区切りリストを生成する

DECLARE @CountryNames NVARCHAR(MAX) 

SET @CountryNames = (SELECT '''' + CountryNames + ''',' 
FROM [Countries].[dbo].[World] 
WHERE UserID = @userID 
FOR XML PATH('')) 

PRINT substring(@CountryNames, 1, len(@CountryNames) - 1) 

FOR XML PATH('')は、カンマ区切り値の単一の行に別の行を連結し、そしてsubstring()機能に使用され末尾のカンマを削除します。

これにより、カーソルをループしてカンマ区切りのリストを作成する必要がなくなります。

この場合、変数@SQLの作成に2つの一重引用符を挿入する必要はありません。すべての必要な二重引用符が上記のステートメント自体で形成されているためです。


EDIT 2:改訂SQL

次はあなたが必要なものを行うには、完全なSQLです。あなたはここで動的SQL文を必要としないのはなぜ

DECLARE @CountryNames NVARCHAR(MAX) 

-- Prepares a comma-separated list of countries, e.g.: 'Africa','Nigeria', 
-- Note that there is a trailing comma 
SET @CountryNames = (SELECT '''' + CountryNames + ''',' 
    FROM [Countries].[dbo].[World] 
    WHERE UserID = @userID 
    FOR XML PATH('')) 

-- Remove the trailing comma 
SET @CountryNames = substring(@CountryNames, 1, len(@CountryNames) - 1) 

DECLARE @SQL nvarchar(MAX) 
SET @SQL = 'SELECT * FROM [Information].[dbo].[Media] WHERE Country_Name IN('+ @CountryNames +')' 

EXEC sp_executesql @SQL 
関連する問題