web-dev-qa-db-ja.com

関数/ストアドプロシージャの作成時のスキーマチェックの無効化

SQL Server 2008 R2データベースへの変更を実行するプロセスを自動化しようとしています。私が配置したプロセスは、ストアドプロシージャと関数を削除して再作成し、テーブル/列/データを変更するスクリプトを実行します。残念ながら、スクリプトの1つでは、関数の1つを最初に配置する必要があります。ただし、最初にテーブル/列/データ変更スクリプトから追加される列に依存しているため、最初にすべてのストアドプロシージャ/関数の変更を実行することはできません。

SQL Serverが関数/ SPの定義で使用される列を検証せずに、ストアドプロシージャと関数を実行できるかどうか疑問に思っていましたか?探してみましたが、これを有効にするための条件やコマンドが見つかりませんでした。

18
Brian Mains

まだ存在しないオブジェクトを参照するストアドプロシージャ(テーブルや関数など)を作成できます。既に存在するオブジェクトにまだ存在しない列を参照するストアドプロシージャを作成することはできません。これは延期された名前解決の両刃の剣です-SQL Serverは、すべてではなく一部のケースで疑いの利益を提供します。 ErlandのSET STRICT_CHECKS ON;に関するアイデアを参考にして、これが機能する場所と機能しない場所についていくつかのアイデアを入手してください。

http://www.sommarskog.se/strict_checks.html

(そして、彼があなたが望んでいるものと反対の極性をどのようにしたいのか-あなたは存在に関係なく何でもコンパイルできるようにしたい、そして彼はすべての単一の列またはテーブルがチェックされることを望んでいる。)

要求されていますが、SET DEFERRED_NAME_RESOLUTION OFF;のような設定はありません。

http://connect.Microsoft.com/sql/127152

そして、IGNORE ALL_RESOLUTION;のような設定はありません。


次のようないくつかの方法でこれを回避できます。

(a)影響を受けるストアドプロシージャで動的SQLを使用します。

(b)何もないCREATE PROCEDUREのスタブを作成し、残りのスクリプトを実行してから、実体を持つALTER PROCEDUREを実行します(基本的に、手順を2つのフェーズで展開します)。

(c)操作の順序についてデプロイメントツールをよりスマートにします。テーブルの変更に関数の存在が必要な場合は、それらの変更を最後にスクリプト化します。 RedGateのSQL Compareなどのスキーマ比較ツールは、適切な依存関係の順序でスクリプトを生成するのに非常に適しています。使用しているツールについては言及していませんが、そうでない場合は...

(d) Martin Smithには興味深い回避策があります ですが、まだ使っていません。

21
Aaron Bertrand

問題のオブジェクトを最初に削除または名前変更するストアード・プロシージャーを作成してから、元のストアード・プロシージャーを動的SQLとして実行できます。これにより、動的SQLを使用するために実際のストアドプロシージャを書き直す必要がなくなります。

以下のコードは、まだ存在しない列を参照するストアドプロシージャを実行します(Expense_Super_Compare)

IF OBJECT_ID('Expense_Super_Compare_Results', 'U') IS NOT NULL
BEGIN
     EXEC('DROP TABLE Expense_Super_Compare_Results');
END

exec('exec dbo.Expense_Super_Compare');
1
Lou Fancy