2017-01-18 6 views
2

次の動的クエリを実行しようとしていますが、私はこのクエリに動的パラメータを渡しました。動的クエリでnull値を渡す方法

DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) 
INSERT INTO @TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM @TABLE 
        WHERE NAME='''[email protected]+'''' 
PRINT @SQL 

しかし、結果やエラーはありません。 誰かがこの問題を解決します。

+0

NULLの連絡先がNULLのままであるため、ISNULLを@Nameに使用できます。 –

+0

なぜ動的SQLがありますか? –

+0

意図的にNULL値をクエリに渡したい場合、またはクエリが失敗している理由が不明な場合は、明確にしてください。 NULLを渡したい場合は、 '='演算子を使用してNULL比較を行うべきではないため、文字列を変更する必要があります。 – DK5

答えて

0

NULLを文字列に連結すると、常にNULLだけが得られます。ここで変数@NAMEはNULLなので、@SQLもNULLになります。

@NAMEがNULLの場合、ISNULL関数を使用してデフォルト値を割り当てることができます。

SET @SQL='SELECT * 
      FROM @TABLE 
      WHERE ISNULL(NAME,'''')='''+ISNULL(@NAME,'')+'''' 

しかし、あなたのクエリ内の別の問題があり、はあなたがクエリを実行すると、それはエラーをスロー、動的SQL内@Table_Variableを追加することはできませんが、ここで#Temp_tablesを使用することができます。

0

はスクリプト

1)あなたはNULLにあなたの変数@Nameを設定するには2つの問題があります。これで、NULLとVARCHAR変数を連結すると、結果はNULL文字列になります。 SELECTステートメントを含む変数@SQLが@Nameで連結されるので、NULLになり、EXECUTEでEXECUTEを使用すると、答えは何も返しません。

2)EXECUTEステートメントの範囲外のテーブル変数を宣言しています。あなたは、動的SQLで変数を使用すると、彼らはどちらかでなければならない:

変数の値が渡され、値がの一部となっている。その場合には、あなたが@Name変数でやって、試みのように文字列を連結し
  1. 、他の

    SELECT 'ABC'; 
    
    1. :代わりに変数 DECLARE @Name VARCHAR(20) = 'ABC'; EXEC('SELECT ''' + @Name + ''';');

    の文字列は、上記のステートメントは、次のSQL同等のものを実行します動的SQLステートメント内から変数を変数として使用する方法は、その変数を動的SQL内でのみ宣言することです。そうしないと、動的SQL内で変数が認識されず、SQL文字列の実行時に宣言されていない可変のエラーが発生します。ステートメントの実行時にわかるように、SQLはテーブル変数@Tableを内部から認識できません。このため 回避策は、動的SQL文字列内@Table変数を宣言し、そこに初期化されます。 DECLARE @NAME VARCHAR(20)=NULL, @SQL VARCHAR(MAX); SET @SQL='DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) INSERT INTO @TABLE SELECT 1,''A'' UNION SELECT 2,''B'' UNION SELECT 3,NULL; SELECT * FROM @TABLE WHERE NAME='''[email protected]+'''';

覚えておくべき重要な点は、動的SQL文字列から別のバッチで実行される、ということですそれが呼び出されたものです。つまり、@Table変数を動的SQL文字列の中に宣言すると、動的SQL文字列の期間とスコープだけが存在し、それ以降は存在しません。したがって、@テーブル変数に加えた変更は、@テーブル変数が存在しなくなるので、ダイナミックSQLステートメントの後には存在しません。 同様にSQL文字列の外に@Table変数を宣言すると、動的@SQLバッチでのその使用が妨げられます。

0

EXECステートメントでは、テーブル変数にアクセスできません。表変数は接続の範囲に固有なためです。 Execステートメントは、別のセッション(接続)でコードを実行します。

ので、代わりにあなたは一時テーブル(#)

CREATE TABLE #TABLE (ID INT,NAME VARCHAR(10)) 
INSERT INTO #TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM #TABLE 
        WHERE NAME ' 
SELECT @SQL = @SQL + CASE WHEN @NAME IS NULL THEN 'IS NULL' ELSE '='''[email protected]+'''' END 
PRINT @SQL 
0

よりもむしろ一緒に文字列を連結を使用することができ、私は、文字列値のいずれかで@NAME変数を置き換えるために、設定されたステートメントを追加またはNULLです。

DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) 
INSERT INTO @TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM @TABLE 
        WHERE NAME [NAME]' 
set @SQL = replace(@SQL, '[NAME]', isnull('= ''' + @NAME + '''', 'IS NULL')) 
print @SQL 
関連する問題