简体   繁体   中英

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

I have several long running Sybase stored procedures with print statements that output progress messages. We've always executed these SPs using isql or manually through aseisql or sqladvantage (all sybase specific tools). These tools correctly display the print messages as soon as they are output by the SP as the SPs all contain "set flushmessage on".

I've written a C# console wrapper app which generically executes a procedure and transforms the results. However frustratingly I have been unable to capture the print messages and write them out to std out. This seems like it should be trivial and I'm amazed I cant turn up much on it on the internet.

I'm using an ODBC connection and am adding the necessary event handler to the InfoMessage callback hook. In my testing, this is getting called with the print statement messages - however not in realtime as they are issued . It doesn't seem to get called until a resultset is sent back to the client, then it is called once only with all messages. I've tried using a DataAdapter to fill a DataSet, using ExecuteNonQuery, ExecuteReader and so on and it doesn't seem to change the behaviour. I've also tried both the Sybase System 11 and Adaptive Server Enterprise ODBC drivers and no difference.

So my question is twofold:

1) firstly I'd like to understand exactly what is occuring here - I know the stored procedure is immediately sending the message to the database server but it's obviously being cached somewhere - either not read off the server by the ODBC driver or read and cached in the driver memory itself? - Normally I just think of the calling thread in my app blocking on a database call, but trying to think through what's really going on I guess the thread is busy within the driver code polling for results/messages and I don't know how that kind of works in with the callback function and when that is processed. Debugging in my app it seems to be called just before I get control back to process results.

2) Secondly, what I'd really like to know is whether there is any way to change the behaviour so the messages are sent back to the client immediately.

Any help would be greatly appreciated, but please refrain from "why don't you do things XYZ way instead" suggestions as I'm really after specific help solving and understanding this problem -I can think of many alternatives should the issue prove to be insurmountable.

Here's a little test-rig to illutsrate the code:

Stored proc:

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 Code snippet:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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