簡體   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