Процедура Informix — как вернуть пустую таблицу?

Мне нужно создать процедуру Informix, чтобы возвращать таблицу со строками, если я нашел какое-то значение, и пустую таблицу, если значение не найдено.

Я знаю, как вернуть таблицу со строками, но не знаю, как вернуть пустую таблицу; кто-нибудь может помочь?

CREATE row type AType (
  id VARCHAR(255),
  name VARCHAR(255)
);


CREATE PROCEDURE getmeasurement (p_date DATETIME YEAR TO SECOND)
RETURNING MULTISET(AType NOT NULL);

    DEFINE AType_TABLE MULTISET (AType NOT NULL);
    DEFINE v_id VARCHAR(255);
    DEFINE v_name VARCHAR(255);
    ....
    IF( FoundValue ) THEN
        -- INSERT INTO TABLE
        INSERT INTO TABLE (AType_TABLE) VALUES (ROW(v_id,v_name)::AType);     
    ELSE
        // how to initial a AType_TABLE instance with empty records.
    END IF
    ....
    RETURN AType_TABLE;

END PROCEDURE;

person David Kin    schedule 19.02.2013    source источник
comment
Всегда полезно сделать процедуру компилируемой и использовать комментарии SQL вместо комментариев C++ (это меня зацепило!).   -  person Jonathan Leffler    schedule 25.02.2013


Ответы (1)


Несмотря на то, что написано в SQL Руководство по синтаксису, процедуры SPL (язык хранимых процедур) могут возвращать типы коллекций (COLLECT, SET, MULTISET или LIST). Ранее на этой неделе я сообщил об ошибке в документации, которая ввела меня в заблуждение.

Мне не удается скомпилировать эту процедуру под Informix 11.70.FC6 в Mac OS X 10.7.5, но возникает следующая ошибка:

SQL -9905: [Internal] No extended type information for domain.

Я столкнулся с различными проблемами, пытаясь использовать различные варианты приведенного выше кода. Кажется, у вас не может быть предложения WHERE в DELETE из мультинабора (другое сообщение об ошибке). Вы также можете столкнуться с проблемами, если откатите создание типа, а затем повторите попытку.

Тем не менее, я смог протестировать его с предварительным выпуском 11.70.FC8 в Linux (RHEL 5, x86/64) и получил желаемый результат:

CREATE ROW TYPE IF NOT EXISTS AType
(
    id   VARCHAR(255),
    name VARCHAR(255)
);

CREATE PROCEDURE getmeasurement (p_date DATETIME YEAR TO SECOND)
        RETURNING MULTISET(AType NOT NULL);

    DEFINE AType_TABLE MULTISET(AType NOT NULL);
    DEFINE v_id VARCHAR(255);
    DEFINE v_name VARCHAR(255);

    LET v_id = "Polynomial - " || p_date;
    LET v_name = "Euclid's Geometry of the Plane";
    INSERT INTO TABLE (AType_TABLE) VALUES(ROW(v_id, v_name)::AType);
    IF 1 = 1 THEN
        -- how TO initial a AType_TABLE instance WITH empty records.
        DELETE FROM TABLE(AType_TABLE);
    END IF

    RETURN AType_TABLE;

END PROCEDURE;

EXECUTE PROCEDURE getmeasurement(CURRENT);

ROLLBACK;

Результат был:

MULTISET{}

который является пустым мультимножеством. Если вы сначала не вставите что-то в мультимножество, удаление завершится ошибкой. Это немного странно.

Резюме

Вы можете быть в порядке с Informix 11.70.xC7; это может работать и на некоторых других версиях. Но, скорее всего, существует множество версий Informix, в которых он не работает.

person Jonathan Leffler    schedule 20.02.2013
comment
Большое спасибо за ваше решение, я попробовал свою версию Informix Growth (Windows) 11.70.FC7GE, но это вызвало сбой базы данных, в настоящее время до сих пор не знаю, почему. Так что пока я просто позволяю ему возвращать запись со значением и проверяю ее в своем java-коде. - person David Kin; 26.02.2013