Question

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?

Was it helpful?

Solution

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.

OTHER TIPS

If you can avoid using the context connection you can circumvent this issue. Creating a new SqlConnection with a conventional connection string (with the Enlist option set to false to prevent usage of the same transaction context if necessary) will allow you to use multithreading in a SQL CLR context.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top