Используйте Informix Object Interface для C++ для хранимых процедур/функций без параметров

Это просто - есть ли способ использовать эту библиотеку для вызова хранимой процедуры или функции, которая возвращает более одного результата? Я знаю о ITRoutingManager, но, похоже, он возвращает только одно значение.

В деталях, вот что я имею в виду:

CREATE FUNCTION test_out1( pin INT )
    RETURNING INT;

    DEFINE param INT;
    LET param = 321;

    RETURN param;

END FUNCTION;

Возвращает 321, я могу получить значение с помощью ITValue и ITConversions. Так что это нормально. Но нет следующего:

CREATE FUNCTION test_out2( pin INT )
    RETURNING INT, INT;

    DEFINE param INT;
    LET param = 321;

    DEFINE param2 INT;
    LET param2 = 123;

    RETURN param, param2;

END FUNCTION;

Когда я делаю routine.GetRoutine( "function test_out2( int )" ), все нормально, так что с этим проблем нет. Но посмотрите это:

std::cout << "Result type: " << routine.ResultType()->Name() IsRow() ? "row, " : ", " )
        << (routine.ResultType()->IsCollection() ? "collection, " : ", " )
        << routine.ResultType()->Quality() << "\n\n";

печатает integer, , , null, обратите внимание на целое число.. Почему целое число, а не строка, например. И как получить 2 значения, возвращаемые функцией? Еще один интересный факт - возвращаемое значение равно 0 (когда я конвертирую его в int, используя класс ITConversions), а не 123 и не 321..

Должен быть способ. Это специальная библиотека, написанная для серверов Informix разработчиками Informix и было бы странно, если бы это было невозможно.

То же самое для функций, но я думаю, что там то же самое.


ПРИМЕЧАНИЕ. В общем случае нет таких параметров, как выходные параметры, для процедур/функций informix (Informix: процедура с выходными параметрами?)


person Kiril Kirov    schedule 31.03.2011    source источник
comment
Вы переоцениваете полезность пакета OIC++. Он написан на архаичном достандартном C++ с использованием макросов вместо шаблонов. Он не подвергался серьезным изменениям с тех пор, как был написан примерно в 1996 году — несколько лет назад он был немного подчищен, так что компилятор компилировал его с меньшим количеством жалоб. Обратите внимание на «меньше жалоб», а не на «нет жалоб». Я бы не рекомендовал его для нового кода.   -  person Jonathan Leffler    schedule 31.03.2011
comment
@Jonathan Leffler - альтернативой для меня является использование драйвера ODBC, он отлично работает с сервером Informix. Я хотел использовать пакет OIC++, так как он предназначен только для Informix, поэтому я ожидал, что он будет быстрее (это для системы реального времени с очень высокой нагрузкой). Но оказалось, что он еще медленнее, за исключением случаев, когда используется ITRoutineManager — тогда благодаря этому классу производительность вдвое лучше. Но только потом.. Итак, не могли бы вы посоветовать? Я предполагаю, что ODBC был бы лучшим выбором? Заранее большое спасибо!   -  person Kiril Kirov    schedule 31.03.2011
comment
Я про unixODBC, забыл упомянуть. Я видел описание в вашем профиле (давний пользователь и разработчик Informix, опыт работы с C и Unix), и я буду очень признателен за ваше мнение.   -  person Kiril Kirov    schedule 31.03.2011
comment
Я бы рекомендовал использовать ODBC вместо OIC++. Интерфейс OIC++ построен поверх другой библиотеки, DMI, которая, в свою очередь, построена поверх другой библиотеки, которая обращается к СУБД — я забыл, основана ли она на ESQL/C или ODBC, или на одной из основных библиотек, на которых они построены. . Использование unixODBC в качестве диспетчера драйверов и соответствующего драйвера ODBC имеет для меня больше смысла, чем использование OIC++.   -  person Jonathan Leffler    schedule 31.03.2011
comment
Большое спасибо! Пожалуйста, добавьте эти вещи в свой ответ в качестве предложения, и я с удовольствием приму его (:   -  person Kiril Kirov    schedule 31.03.2011


Ответы (1)


Как вы заметили, Informix на самом деле не имеет параметров 'OUT'; он возвращает значения.

В обычном ESQL/C вы обрабатываете список выходных значений симметрично списку входных значений; Поэтому я ожидал бы сделать то же самое с этим кодом. Какой бы метод вы ни использовали для передачи 2 аргументов в функцию, скорее всего, но ни в коем случае не гарантируется, что вы получите несколько возвращаемых значений.

В случае сомнений относитесь к нему так же, как к оператору SELECT, который возвращает несколько строк. То есть делать аналоги:

 PREPARE s FROM "EXECUTE PROCEDURE test_out2(?)";
 DECLARE c CURSOR FOR s;
 OPEN c USING :input_value;
 while (sqlca.sqlcode == 0)
 {
     FETCH c INTO :out_value1, :out_value2;
     if (sqlca.sqlcode != 0)
         break;
     ...use values...
 }
 CLOSE c;
 FREE c;
 FREE s;

Я бы рекомендовал использовать ODBC вместо OIC++. Интерфейс OIC++ построен поверх другой библиотеки, DMI, которая, в свою очередь, построена поверх другой библиотеки, которая обращается к СУБД — я забыл, основана ли она на ESQL/C или ODBC, или на одной из основных библиотек, на которых они построены. . Использование unixODBC в качестве диспетчера драйверов и соответствующего драйвера ODBC имеет для меня больше смысла, чем использование OIC++.


Я понятия не имею, как это выглядит в OIC++; Я никогда им не пользовался, а лишь поверхностно обслуживал его.

В целом, вам лучше не использовать OIC++ для новой работы. Informix продолжает распространять его для обратной совместимости, а не для поощрения нового использования.

person Jonathan Leffler    schedule 31.03.2011
comment
да, это работает нормально, но в два раза медленнее, чем при использовании класса ITRoutineManager, и тогда действительно лучше использовать ODBC. - person Kiril Kirov; 01.04.2011
comment
Теперь я могу подтвердить, что ODBC быстрее, и что OIC++ построен поверх DMI, который построен поверх ESQL/C (: - person Kiril Kirov; 05.04.2011