2

でストアド プロシージャを呼び出す CLR トリガーがありますBeginInvoke。ストアド プロシージャで SqlComman を呼び出そうとしましたが、次のメッセージが表示されます。要求された操作には、Sql Server 実行スレッドが必要です。現在のスレッドは、ユーザー コードまたはその他の非 SQL Server エンジン コードによって開始されました。

私は SP でこれを行う必要がBeginInvokeあり、待機のために で SP を呼び出さなければなりません。

コード:

[SqlProcedure()]
public static void MySendData( String crudType, String sourceTable, ... ) {
    SqlCommand sqlDeleteComm;

    String temp = String.Empty;

    using( SqlConnection conn = new SqlConnection( "context connection=true" ) ) {

        sqlDeleteComm = new SqlCommand( "DELETE FROM #TEMP_TABLE" );
        sqlDeleteComm.Connection = conn;

        try {
            conn.Open();
            sqlDeleteComm.ExecuteNonQuery();
            conn.Close();
        } catch( Exception ex ) {
            // --- here ---
            // The requested operation requires a Sql Server execution thread.  The current thread was started by user code or other non-Sql Server engine code.
        }
    }
    ...
}

[Microsoft.SqlServer.Server.SqlTrigger( Name = "MyTrigger", Target = "MyTable", Event = "FOR UPDATE, INSERT, DELETE" )]
public static void MyTrigger() {
    SqlTriggerContext myContext = SqlContext.TriggerContext;
    MyDelagate d;
    SqlCommand sqlComm;
    SqlDataReader reader;

    if( connection.State != ConnectionState.Open ) {
        connection.Open();
    }

    switch( myContext.TriggerAction ) {
        case TriggerAction.Update:
            sqlComm = new SqlCommand( "SELECT X, Y FROM Inserted" );
            sqlComm.Connection = connection;

            reader = sqlComm.ExecuteReader();
            try {
                reader.Read();
                d = new MyDelagate( MySendData );
                d.BeginInvoke( "Update", "MyTable", ( Int32 )reader[ 0 ], ( Int32 )reader[ 1 ], null, null );
            } catch( Exception ex ) {
            } finally {
                reader.Close();
            }
            break;
            ...
    }
}

SP で SQL クエリを呼び出すすべての場合、どうすればよいでしょうか?

4

2 に答える 2

1

SQL Server が CLR コードを実行するスレッドの外では、コンテキスト接続を使用できません。これはサーバーの信頼性を確保するためです。SQL Server はカスタム CLR ホスティングを使用しており、独自のスレッドをまったくスピンできることに驚きました。contextで標準の ADO.NET を使用して、T-SQLMySendDataから呼び出すことができますが、別のスレッドで実行する方法はありません。データベース レベルで非同期/並列処理が本当に必要な場合は、SQL Server Broker を調べてください。MyTriggerSqlCommandSqlConnection

于 2012-03-22T12:16:15.640 に答える
0

コンテキスト接続の使用を避けることができれば、この問題を回避できます。従来の接続文字列 (必要に応じて同じトランザクション コンテキストを使用しないように Enlist オプションを false に設定) を使用して新しい SqlConnection を作成すると、SQL CLR コンテキストでマルチスレッドを使用できます。

于 2019-08-04T14:08:21.133 に答える