为啥这个 SQL 存储过程需要创建一个临时表才能工作(返回结果)?

Posted

技术标签:

【中文标题】为啥这个 SQL 存储过程需要创建一个临时表才能工作(返回结果)?【英文标题】:Why does this SQL stored procedure require that a temp table be created for it to work (return results)?为什么这个 SQL 存储过程需要创建一个临时表才能工作(返回结果)? 【发布时间】:2011-09-08 04:42:11 【问题描述】:

IBM Informix 动态服务器版本 11.50.FC6

我正在研究一个小型存储过程,它会从表中获取名称字段并将它们解析为最多 8 个字符的“用户名”。

这是我正在尝试的代码:

CREATE PROCEDURE build_jics_user (pid INT)
    RETURNING CHAR(8) AS username;
    SELECT LOWER((SUBSTR(firstname,0,1))||(SUBSTR(lastname,0,7))) username
    FROM id_rec
    WHERE id = pid;
END PROCEDURE;

执行时返回的错误是:

  659: INTO TEMP table required for SELECT statement.
Error in line 5
Near character position 15

我不明白召唤临时表的意义何在,我也无法在网上找到任何类似的简单示例且不会出错。

有人知道我错过了什么吗?

【问题讨论】:

【参考方案1】:

你想说的是:

CREATE PROCEDURE build_jics_user (pid INT)
    RETURNING CHAR(8);
    DEFINE username CHAR(8);
    SELECT LOWER((SUBSTR(firstname,0,1))||(SUBSTR(lastname,0,7))) INTO username
      FROM id_rec
      WHERE id = pid;
    RETURN username;
END PROCEDURE;

...并像这样执行它:

EXECUTE PROCEDURE build_jics_user(42);

更新

如果它的目的是成为一个函数,在其他一些 SQL 中需要它,那么您可以执行以下操作:

CREATE FUNCTION jics_user(fname VARCHAR(255), lname VARCHAR(255))
    RETURNING CHAR(8);
    RETURN LOWER(SUBSTR(fname,0,1) || SUBSTR(lname,0,7));
END FUNCTION;

...并像这样执行它:

SELECT id, firstname, lastname, jics_user(firstname, lastname) AS jics_user, ...
  FROM id_rec;

PROCEDURE 和 FUNCTION 之间没有真正的技术区别,更多的是关于如何使用它的断言。

【讨论】:

谢谢 - 对创建程序有点陌生 &| Informix 上的触发器 乐于助人。如果您想在已经读取 id_rec 表的查询中将其用作函数,那么这是一种非常低效的方法。请参阅我的更新答案。【参考方案2】:

这个seems to be per design(这一定是因为没有'网上同样简单的例子')。显然,无论您在存储过程中使用 SELECT 语句提取什么数据,都不能直接返回它们。您应该将它们存储在临时表或变量中以备后用。

您的 SELECT 语句很可能应该是这样的

SELECT LOWER((SUBSTR(firstname,0,1))||(SUBSTR(lastname,0,7))) INTO username
FROM id_rec
WHERE id = pid;

【讨论】:

在这种情况下很可能是一个变量,因为函数只返回一个值 谢谢!事实上,我现在可以看到该过程中发生了什么(在这种情况下,这似乎确实是一个函数)。用建议更新了答案。

以上是关于为啥这个 SQL 存储过程需要创建一个临时表才能工作(返回结果)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 SQL 中使用表值函数而不是临时表?

SQL Server 存储过程创建临时表并插入值

SQL临时表使用

Informix SQL 11.5 创建没有临时表的存储过程

ORACLE存储过程创建临时表并插入数据。

oracle 怎么在存储过程中创建一个临时表,在里面插入数据,再查找这个临时表的所有数据,最后drop这个表。