CLR存储过程需要一个Sql Server执行线程

3
我有一个CLR触发器,它使用BeginInvoke调用存储过程。在存储过程中,我尝试调用SqlComman,但是出现以下错误:所请求的操作需要一个SQL Server执行线程。当前线程是由用户代码或其他非SQL Server引擎代码启动的。 我必须在存储过程中执行这些操作,并且必须使用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查询?

2个回答

2

在 SQL Server 运行 CLR 代码的线程之外,您不能使用上下文连接;这是为了确保服务器的可靠性 - SQL Server 使用自定义 CLR 托管,我很惊讶它允许您自己启动线程。您可以在 T-SQL 中使用标准 ADO.NET SqlCommand 以及上下文 SqlConnectionMyTrigger 调用 MySendData,但无法在单独的线程中运行。如果您真的想在数据库层实现异步/并行操作,请了解 SQL Server Broker。


0

如果您可以避免使用上下文连接,就可以规避此问题。使用传统的连接字符串创建一个新的SqlConnection(将Enlist选项设置为false以防必要时使用相同的事务上下文),这将允许您在SQL CLR上下文中使用多线程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接