繁体   English   中英

数据库连接InfoMessage回调不会立即为存储的proc打印语句触发

[英]DB connection InfoMessage callback not firing immediately for stored proc print statements

我有几个长时间运行的Sybase存储过程,带有输出进度消息的打印语句。 我们一直使用isql或通过aseisql或sqladvantage(所有sybase特定工具)手动执行这些SP。 由于SP都包含“ set flushmessage on”,因此这些工具在SP输出后立即正确显示打印消息。

我编写了一个C#控制台包装应用程序,该应用程序通常执行一个过程并转换结果。 但是,令人沮丧的是,我无法捕获打印消息并将其写出到标准输出。 看来这应该是微不足道的,但令我惊讶的是,我无法在互联网上找到太多有关它的信息。

我正在使用ODBC连接,并将必要的事件处理程序添加到InfoMessage回调挂钩。 在我的测试中,这是通过print语句消息调用的- 但是由于它们不是实时发出的 直到结果集发送回客户端之前,它似乎没有被调用,然后仅对所有消息调用一次。 我尝试过使用DataAdapter来填充数据集,并使用ExecuteNonQuery,ExecuteReader等,并且它似乎并没有改变行为。 我还尝试了Sybase System 11和Adaptive Server Enterprise ODBC驱动程序,两者没有区别。

所以我的问题是双重的:

1)首先,我想确切地了解这里发生的事情-我知道存储过程会立即将消息发送到数据库服务器,但是显然它被缓存在某个地方-要么不被ODBC驱动程序从服务器上读取,要么被读取并缓存在驱动程序内存本身中? -通常,我只是想到应用程序中的调用线程在数据库调用中阻塞,但是尝试考虑到底发生了什么,我猜想该线程在驱动程序代码轮询中忙于结果/消息的轮询,我不知道该怎么做可以与回调函数配合使用,以及何时进行处理。 在我的应用程序中调试似乎在我重新获得控制权以处理结果之前被调用。

2)其次,我真正想知道的是是否有任何方法可以更改行为,以便将消息立即发送回客户端。

任何帮助将不胜感激,但请避免使用“为什么不以XYZ方式做事”建议,因为我确实是在寻求具体帮助来解决和理解此问题之后-我可以想到许多替代方案,以证明问题出在不可逾越。

这是一些说明代码的测试平台:

存储过程:

create procedure sp_test
as
begin
    set flushmessage on

    print "Step 1"

    waitfor delay "00:00:10"

    print "Step 2"

    waitfor delay "00:00:10"

    select 10 as "number"  -- preferably put some sort of select from a table here

    print "Final Step"

end
go
grant execute on sp_test to public
go

.NET代码段:

using System.Collections.Generic;
using System.Data;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
    static void Main(string[] args)
    {
        using (var conn = new OdbcConnection(@"<connection string here>"))
        {
            conn.InfoMessage += OnInfoMessage;
            conn.Open();
            var command = new OdbcCommand("sp_test", conn);
            command.Timeout = 50000;  // i added this later syntax might be wrong
            var ds = new DataSet();
            var da = new OdbcDataAdapter(command);
            da.Fill(ds);
            Console.ReadKey();
        }
    }

    private static void OnInfoMessage(Object sender, OdbcInfoMessageEventArgs args)
    {
        foreach (OdbcError error in args.Errors)
        {
            Console.WriteLine(error.Message);
        }
    }
}
}

RAISERROR(...) WITH NOWAIT而不是PRINT尝试RAISERROR(...) WITH NOWAIT

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM