sql >> データベース >  >> RDS >> Sqlserver

動的SQLエラー:「CREATETRIGGER」はクエリバッチの最初のステートメントである必要があります

    SSMS(または他の同様のツール)を使用して、 thisによって生成されたコードを実行する場合 スクリプトでは、まったく同じエラーが発生します。バッチ区切り文字(GO)を挿入すると、正常に実行される可能性があります。 )、しかし今はそうではないので、SSMSでも同じ問題に直面するでしょう。

    一方、GOを入れられない理由 動的スクリプトでは、GO これはSQLステートメントではなく、SSMSやその他のツールによって認識される区切り文字にすぎません。おそらくあなたはすでにそれを知っています。

    とにかく、GOのポイント ツールは、コードを分割し、その部分を別々に実行する必要があることを認識します。 。そして、それは個別に 、コードでも行う必要があります。

    したがって、次のオプションがあります。

    • EXEC sp_execute @sqlを挿入します トリガーをドロップする部分の直後で、@sqlの値をリセットします 次に、定義部分を順番に保存して実行します。

    • @sql1の2つの変数を使用します および@sql2 、IF EXISTS/DROPパーツを@sql1に保存します 、CREATETRIGGERoneを@sql2に挿入します 、次に両方のスクリプトを実行します(ここでも別々に)。

    しかし、すでにわかっているように、別の問題に直面します。別のデータベースのコンテキストでステートメントを実行せずに、別のデータベースでトリガーを作成することはできません。

    現在、必要なコンテキストを提供する方法は2つあります。

    1)USEを使用する ステートメント;

    2)EXEC targetdatabase..sp_executesql N'…'

    明らかに、最初のオプションはここでは機能しません。USE …を追加することはできません。 CREATE TRIGGERの前 、後者がバッチ内の唯一のステートメントである必要があるためです。

    2番目のオプションはできます 使用できますが、動的性の追加レイヤーが必要になります (それが単語かどうかはわかりません)。これは、データベース名がここでのパラメーターであるため、EXEC targetdatabase..sp_executesql N'…' as 動的スクリプトであり、実行する実際のスクリプト自体が動的スクリプトであると想定されているため、2回ネストされます。

    したがって、(2番目の)EXEC sp_executesql @sql;の前に 次の行を追加します:

    SET @sql = N'EXEC ' + @dbname + '..sp_executesql N'''
               + REPLACE(@sql, '''', '''''') + '''';
    

    ご覧のとおり、@sqlのコンテンツを統合するには ネストされた動的スクリプトとして適切に、それらは一重引用符で囲む必要があります。同じ理由で、すべての引用符は @sql 2倍にする必要があります(例: REPLACE() 機能 、上記のステートメントのように)。



    1. SQL:SQLを最適化するのを手伝ってください

    2. PESSIMESTICLOCKがMySQLにアクセスするSpringDataで機能しない

    3. UTC ISO8601の日付をMySQLデータベースに保存するにはどうすればよいですか?

    4. MariaDB JSON_CONTAINS()の説明