Локальные переменные в скрипте Informix - PullRequest
3 голосов
/ 23 мая 2011

Я должен сделать большой скрипт обновления, а не SPL (хранимая процедура).Это должно быть написано для Informix db.

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

Я знаю, что могу получить доступк последовательному, выполнив это:

SELECT DISTINCT dbinfo('sqlca.sqlerrd1') FROM systables

, но я не могу определить локальную переменную для хранения этого до вставки в следующую таблицу.

Я хочу сделать это:

insert into table1 (serial, data1, data2) values (0, 'newdata1', 'newdata2');
define serial1 as int;
let serial1 = SELECT DISTINCT dbinfo('sqlca.sqlerrd1') FROM systables;
insert into table2 (serial, data1, data2) values (0, serial1, 'newdata3');

Но, конечно, Informix блокирует заданную строку.

Есть ли способ сделать это без необходимости создавать это как хранимую процедуру, запустить ее один раз, а затем удалить процедуру

Ответы [ 2 ]

2 голосов
/ 25 мая 2011

Если количество столбцов в задействованных таблицах меньше, чем в вашем примере, тогда вы можете сделать SPL постоянным и использовать его для вставки ваших данных, например:

EXECUTE PROCEDURE insert_related_tables('newdata1','newdata2','newdata3');

Очевидно, что это не очень хорошо масштабируется, но это нормально для вашего примера.

Еще одна мысль, которая расширяет пример Джонатана и решает любые проблемы параллелизма, которые могут возникнуть при использовании MAX (), будет включать DBINFO('sessionid') в Table3:

DELETE FROM Table3 WHERE sessionid = DBINFO('sessionid');
INSERT INTO Table1 (...);
INSERT INTO Table3 (sessionid, value)
  VALUES (DBINFO('sessionid'), DBINFO('sqlca.sqlerrd1'));
INSERT INTO Table2 
  VALUES (0, (SELECT value FROM Table3
              WHERE sessionid = DBINFO('sessionid'), 'newdata3');
...

Вы также можете сделать Table3 таблицей TEMP:

INSERT INTO Table1 (...);
SELECT DISTINCT DBINFO('sqlca.sqlerrd1') AS serial_value
  FROM some_dummy_table_like_systables
INTO TEMP Table3 WITH NO LOG;
INSERT INTO Table2 (...);
0 голосов
/ 24 мая 2011

Informix не предоставляет механизм вне хранимых процедур для «локальных переменных» нужного вам типа.Однако в приведенном вами ограниченном примере это работает:

CREATE TABLE Table1
(
    serial SERIAL(123) NOT NULL,
    data1  VARCHAR(32) NOT NULL,
    data2  VARCHAR(32) NOT NULL
);
CREATE TABLE Table2
(
    serial SERIAL      NOT NULL,
    data1  INTEGER     NOT NULL,
    data2  VARCHAR(32) NOT NULL
);

INSERT INTO Table1(Serial, Data1, Data2)
    VALUES(0, 'newdata1', 'newdata2');
INSERT INTO Table2(Serial, Data1, Data2)
    VALUES(0, DBINFO('sqlca.sqlerrd1'), 'newdata3');

SELECT * FROM Table1;

123   newdata1     newdata2

SELECT * FROM Table2;

1     123          newdata3

Однако это работает только потому, что вам нужно вставить одну строку в таблицу 2.Если вам нужно было вставить больше, техника не сработает.Вы могли бы, я полагаю, использовать:

CREATE TEMP TABLE Table3
(
    value   INTEGER NOT NULL
);

INSERT INTO Table1(Serial, Data1, Data2)
    VALUES(0, 'newdata1', 'newdata2');
INSERT INTO Table3(Value)
    VALUES(DBINFO('sqlca.sqlerrd1'));
INSERT INTO Table2(Serial, Data1, Data2)
    VALUES(0, (SELECT MAX(value) FROM Table3), 'newdata3');
INSERT INTO Table2(Serial, Data1, Data2)
    VALUES(0, (SELECT MAX(value) FROM Table3), 'newdata4');

И так далее ... временная таблица для Table3 позволяет избежать проблем с параллелизмом и MAX ().

...