Informix 脚本中的局部变量

发布于 2024-11-09 00:13:02 字数 608 浏览 5 评论 0原文

我必须做一个大的更新脚本 - 而不是 SPL(存储过程)。 它是为 Informix 数据库编写的。

它涉及将行插入到多个表中,每个表都依赖于插入前一个表的顺序。

我知道我可以通过这样做来访问序列号:

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 当然会在定义行上卡住。

有没有办法做到这一点,而不必将其创建为存储过程,运行一次,然后删除该过程?

I have to do a big update script - not an SPL (stored procedure).
It's to be written for an Informix db.

It involves inserting rows into multiple tables, each of which relies on the serial of the insert into the previous table.

I know I can get access to the serial by doing this:

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

but I can't seem to define a local variable to store this before the insert into the next table.

I want to do this:

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');

But of course Informix chokes on the define line.

Is there a way to do this without having to create this as a stored procedure, run it once and then delete the procedure?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迎风吟唱 2024-11-16 00:13:02

如果涉及的表中的列数与您的示例一样少,那么您可以使 SPL 永久存在,并使用它来插入数据,即:

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

显然,这不能很好地扩展,但对于您的示例来说是可以的。

的示例并解决使用 MAX() 可能出现的任何并发问题的另一个想法是在 Table3 中包含 DBINFO('sessionid')

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');
...

扩展Jonathan 还可以使 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 (...);

If the number of columns in the tables involved is as few as your example, then you could make the SPL permanent, and use it to insert your data, ie:

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

Obviously that doesn't scale terribly well, but is OK for your example.

Another thought that expands on Jonathan's example and solves any concurrency issues that might arise from the use of MAX() would be to include DBINFO('sessionid') in 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');
...

You could also make Table3 a TEMP table:

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 (...);
明明#如月 2024-11-16 00:13:02

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

但是,这仅适用于您需要在 Table2 中插入一行。如果您需要插入更多,该技术将无法正常工作。我想,您可以使用:

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() 问题。

Informix does not provide a mechanism outside of stored procedures for 'local variables' of the type you want. However, in the limited example you provide, this works:

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

However, this works only because you need to insert one row into Table2. If you needed to insert more, the technique would not work well. You could, I suppose, use:

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');

And so on...the temporary table for Table3 avoids problems with concurrency and MAX().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文