0

単純な sql-server update トリガーの場合、次のようなクラスを作成できます。

[Microsoft.SqlServer.Server.SqlTrigger (Name="MyTrigger", Target="[dbo].[MyTable]", Event="FOR UPDATE")]
public static void MyTrigger() { //... my code }

しかし、1 つの列の更新でのみトリガーしたい場合は、次のように動作します。

create trigger myTrigger
on myTable
for update as
if update(MyColumn)
begin
    -- my code
end

どのようなMicrosoft.SqlServer.Server.SqlTrigger属性を使用すればよいですか?

4

1 に答える 1

1

これはあなたを助けるかもしれません。

[Microsoft.SqlServer.Server.SqlTrigger (Name="Trigger1", Target="Table1", Event="FOR UPDATE")]
public static void Trigger1()
{
    SqlConnection conn = new SqlConnection("context connection=true;");
    SqlCommand cmd = new SqlCommand("select top 0 * from Table1", conn);

    conn.Open();

    SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.SchemaOnly);

    if (SqlContext.TriggerContext.IsUpdatedColumn(dr.GetOrdinal("columnname")))
    {
        SqlContext.Pipe.Send("columnname was updated");
    }
    else
    {
        SqlContext.Pipe.Send("columnname was not updated");
    }

    dr.Close();
    conn.Close();
} 

トリガーを選択的に実行することを防ぐことはできません。列が更新されても常に実行されます。ただし、起動すると COLUMNS_UPDATED() 関数を参照できます。

挿入または更新されたテーブルまたはビューの列を示す varbinary ビット パターンを返します。COLUMNS_UPDATED は、Transact-SQL INSERT または UPDATE トリガーの本体内の任意の場所で使用され、トリガーが特定のアクションを実行する必要があるかどうかをテストします。

そのため、トリガー ロジックを調整して、更新された列に応じて適切なアクションを実行します。

そうは言っても、SQLCLR から WCF を呼び出すことは非常に悪い考えです。トリガーから WCF を呼び出すのはさらに悪いことです。トランザクションがブロック/中断され、HTTP 応答を待って回線をクロールするため、サーバーは本番環境で停止します。HTTP 呼び出しを元に戻すことはできないため、ロールバックが存在する場合、呼び出しは本質的に正しくないことは言うまでもありません。このようなアクションを実行する適切な方法は、キューを使用して操作と WCF 呼び出しを切り離すことです。これは、キューとして使用されるテーブルで行うことができます。真のキューを使用するか、変更追跡を使用することができます。これらのいずれかを使用すると、変更と WCF 呼び出しを切り離すことができ、SQLCLR からではなく、別のプロセスから呼び出しを行うことができます。

ソース: CLR トリガーで特定の列のみが更新される

于 2012-05-24T10:12:49.440 に答える