2012-03-22 173 views
2

我有一個CLR觸發器,它調用存儲過程與BeginInvoke。在存儲過程中,我嘗試調用SqlComman,但得到:請求的操作需要Sql Server執行線程。當前線程是由用戶代碼或其他非Sql Server引擎代碼啓動的。CLR存儲過程需要一個SQL Server執行線程

我必須在SP中做這個事情,因爲等待,我必須給BeginInvoke打電話。

代碼:

[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; 
      ... 
    } 
} 

我怎麼可能,所有調用SQL查詢的SP?

回答

1

你不能使用線程SQL Server之外的情況下連接運行在您的CLR代碼;這是爲了確保服務器的可靠性--SQL Server使用自定義的CLR託管,我很驚訝它允許您旋轉自己的線程。您可以從MyTrigger用T-SQL調用MySendData,使用標準的ADO.NET SqlCommand上下文SqlConnection,但沒有辦法爲它在一個單獨的線程中運行。如果你真的想在數據庫級別上使用異步/並行,請查看SQL Server Broker。