Выполнить конвейерные функции в ODP.NET

Я хочу выбрать данные из конвейерной функции в C# "как раз вовремя". Это означает, что функция передает строку каждую секунду (например, отчет о состоянии), и я хотел бы немедленно получить данные в C#.

Пока у меня есть следующее:

        Oracle.DataAccess.Client.OracleConnection con = new Oracle.DataAccess.Client.OracleConnection("my_connection_string");

        con.Open();

        Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand("SELECT * FROM TABLE(MYPACKAGE.TEST_PIPELINE(10))", con);
        cmd.CommandType = CommandType.Text;

        Oracle.DataAccess.Client.OracleDataReader reader = cmd.ExecuteReader();

        reader.FetchSize = 244;  //record-size in Bytes

        while (reader.Read())
        {
            System.Diagnostics.Debug.WriteLine("Now: " + DateTime.Now.ToString("HH:mm:ss.ffff"));
            System.Diagnostics.Debug.WriteLine("ID: " + reader.GetValue(0));
            System.Diagnostics.Debug.WriteLine("Text: " + reader.GetValue(1));
        }

Моя примерная функция возвращает n (единственный параметр-функция) строк со сном в одну секунду перед RIPE ROW. Если я запускаю этот код, мне нужно ждать десять секунд, пока я не получу десять строк одновременно.

НО, если я запускаю его во второй раз, он работает отлично, я получаю одну строку каждую секунду (всего десять строк). Может быть, только из-за кэширования операторов, когда я добавляю строку

cmd.AddToStatementCache = false; 

Я получаю блоки из десяти строк даже при втором запуске.

Итак, вопрос: у кого-нибудь есть идея, как получить десять строк "точно в срок" (построчно каждую секунду), когда я выполняю код в первый раз?

Большое спасибо!

Ура христианская

1 ответ

Я пытался воспроизвести вашу функцию.

CREATE OR REPLACE PACKAGE BODY PHXDBA.PIPETEST as
    FUNCTION TENSECOND RETURN TENSECOND_TT 
    PIPELINED AS
    ctr NUMBER;
    ts_ot TENSECOND_OT := TENSECOND_OT(NULL);
    BEGIN
        FOR ctr IN 1..10
        LOOP
            ts_ot.CNT := ctr;
            PIPE ROW (ts_ot);
            SYS.DBMS_LOCK.SLEEP(1);
        END LOOP;
    END;
END PIPETEST;
/

К сожалению, это всегда возвращается через 10 секунд, даже в RapidSQL. Так что я либо неправильно это реализовал, либо функция SLEEP прерывает возврат строк по конвейеру.

Другие вопросы по тегам