如何在 INFORMIX 数据库中使用带有 INTO 子句的立即执行

问题描述 投票:0回答:1

我正在尝试使用 informix 数据库中的过程来获取所有表的计数。 但是,我在使用 Dynamic 的 SELECT INTO 语句获取计数时遇到错误 SQL。

错误 - “变量 (v_count) 具有未定义的值。”

***请告诉我如何使用动态 SQL 为“INFORMIX”中的变量赋值(SELECT count() INTO ****

CREATE PROCEDURE all_table_count_proc()
DEFINE v_table_name VARCHAR(70);
DEFINE v_count INT8;
DEFINE x VARCHAR(100);
DEFINE y VARCHAR(100);
DEFINE z VARCHAR(100);
LET x = 'SELECT count(*) INTO v_count ' ;
LET y = ' FROM ';
SELECT 
tabname
INTO
v_table_name
FROM
systables
WHERE
tabtype = 'T'
and tabid = 508;
LET z = x || y || v_table_name;
EXECUTE IMMEDIATE z;
INSERT INTO table_count_details_tbl values(v_table_name,v_count);
END PROCEDURE;
sql dynamic informix
1个回答
0
投票

AFAIK,您不能将 INTO 子句与 EXECUTE IMMEDIATE 一起使用。 EXECUTE IMMEDIATE 不接受输入或输出参数。您必须准备一条语句,声明一个游标,打开、获取、关闭游标,然后释放游标和语句。 AFAIK,您也不能使用 FOREACH 来封装 OPEN、FETCH、CLOSE 序列。

请参阅 SQL 参考手册中的有效语句的限制(与 EXECUTE IMMEDIATE 一起使用)

此版本的代码可以处理任意表名。它没有错误检查 - 因此在同一个表名上运行该过程两次将生成错误,就像给出不存在的表名等一样。您可能希望使用

WHENEVER ERROR
子句来控制错误处理。 MERGE 语句可用于在
table_count_details_tbl
中插入或更新行。

CREATE PROCEDURE table_count_proc(tabname VARCHAR(128))

    DEFINE tabrows BIGINT;
    DEFINE stmt VARCHAR(255);

    LET stmt = 'SELECT COUNT(*) FROM ' || TRIM(tabname);

    PREPARE p FROM stmt;
    DECLARE c CURSOR FOR p;
    OPEN c;
    FETCH c INTO tabrows;
    INSERT INTO table_count_details_tbl VALUES(tabname, tabrows);
    CLOSE c;

    FREE c;
    FREE p;

END PROCEDURE;

此代码“知道”准备好的 SELECT 语句只会选择一行,因此单个 FETCH 就足够了。一般来说,您需要一个循环来获取所有要返回的行。

请注意,我使用

BIGINT
而不是
INT8
。由于特殊的历史原因,
INT8
类型(以及匹配的
SERIAL8
类型)在磁盘上占用 10 个字节(而不是 8 个字节)。当然,浪费的空间并不大,但不要使用
INT8
SERIAL8
类型。
BIGINT
BIGSERIAL
类型在磁盘上占用 8 个字节 — 始终使用它们。

© www.soinside.com 2019 - 2024. All rights reserved.