簡體   English   中英

CLR存儲過程需要Sql Server執行線程

[英]CLR Stored Procedure needs a Sql Server execution thread

我有一個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查詢的人,我該怎么辦?

您不能在線程外部使用上下文連接SQL Server在其中運行CLR代碼。 這是為了確保服務器的可靠性-SQL Server使用自定義CLR托管,我很驚訝它完全允許您旋轉自己的線程。 您可以使用SqlConnection上下文中的標准ADO.NET SqlCommand ,通過T-SQL從MyTrigger調用MySendData ,但是無法在單獨的線程中運行它。 如果您確實希望在數據庫級別實現異步/並行處理,請查看SQL Server Broker。

如果可以避免使用上下文連接,則可以避免此問題。 使用常規的連接字符串(將Enlist選項設置為false,以防止在必要時阻止使用同一事務上下文)創建新的SqlConnection將使您能夠在SQL CLR上下文中使用多線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM