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()
機能
、上記のステートメントのように)。