I've a CLR trigger, which calls a Stored Procedure with BeginInvoke
. In the Stored Procedure I try to call an SqlComman, but I get: The requested operation requires a Sql Server execution thread. The current thread was started by user code or other non-Sql Server engine code.
I have to do this things in the SP, and I have to call the SP with BeginInvoke
, because of the waiting.
The code:
[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;
...
}
}
How could I, for all that call SQL queries in the SP?
You can't use the context connection outside of the thread SQL Server runs your CLR code in; this is to ensure reliability of the server - SQL Server uses custom CLR hosting, and I'm surprised it allowed you to spin your own thread at all. You can call MySendData
from MyTrigger
with T-SQL, using standard ADO.NET SqlCommand
on the context SqlConnection
, but there is no way for it to run in a separate thread. If you really want asynchrony/parrallelism on the database level, look into SQL Server Broker.