1

SqlMetal を実行し、Linq2Sql データ クラスを生成し、ビルドをトリガーするソース管理にチェックインするバッチ ファイルを作成しました。Sql Server 2005 で DDL が変更されるたびに、このスクリプトを実行したいと考えています。

xp_cmdshell を介してバッチ ファイルを実行すると、次のように、トリガーの外側で問題なく動作します。

exec master..xp_cmdshell 'd:\dev\db_triggers\generatedataclasses.bat', no_output

しかし、トリガーとして実行すると、データベースへの接続が常にタイムアウトになり、すべての DDL が失敗します。これが私のトリガーです:

CREATE TRIGGER [Trig_SqlMetal]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS 
AS
exec master..xp_cmdshell 'd:\dev\db_triggers\generatedataclasses.bat', no_output

次の2点についてアドバイスを求めています。

  1. これを機能させます。何らかの理由で、トリガーにあるときは常に失敗し、トリガーにないときは失敗しません。どちらの場合も LocalSystem として実行されるため、セキュリティ関連ではないようです。
  2. SqlMetal での失敗とタイムアウトが DDL 更新の失敗を引き起こさないように、これを非同期的に行います。バッチファイルを別の「start cmd.exe /c otherbatch.bat」でラップしようとしましたが、SQLサーバーを介して実行すると、開始が無視されるようです(DOSからは正常に動作します)。確かに、いくつかのテーブルとピックアップ イベントを確認するためのポーリング プロセスを作成できますが、複雑さを軽減するために、これをトリガー ベースにすることをお勧めします (または、その逆を行っているのでしょうか :))。
4

1 に答える 1

3

作成中のテーブルに関するデータをクエリしようとするため、バッチがブロックされている可能性がありますが、トランザクション内でロックされています(トリガーは、SQLServerがDDL/ DMLステートメントに対して開始する暗黙的なトランザクションの一部です)。トリガーが終了した後。私が知っているSQLServer2005以降での非同期実行の「ほぼ」実用的な方法は、ServiceBrokerだけです。「ServiceBrokerInternalActivation」を探します。実際には、適切に設定するのは少し複雑なので、プーリングオプションを選択することをお勧めします。

于 2009-04-29T13:46:10.503 に答える