【问题标题】:Datasource returned from Informix Stored Proc从 Informix Stored Proc 返回的数据源
【发布时间】:2009-01-16 17:33:22
【问题描述】:

我有一个返回两列和多行的 Informix 存储过程。我可以很好地使用“EXECUTE FUNCTION curr_sess(2009,'SP')”,但是如何将结果放入临时表中。

编辑:我们使用的是 10.00.HC5 版本


测试 Jonathan Leffler 的想法没有奏效。

EXECUTE FUNCTION curr_sess(2009,'SP')

工作正常。然后我做了

CREATE TEMP TABLE t12(yr smallint, sess char(4));

但是当我尝试时

INSERT INTO t12 EXECUTE FUNCTION curr_sess(2009,'SP');

它不起作用,我收到“SPL 例程中的非法 SQL 语句”。错误。


curr_sess 的来源

begin procedure

DEFINE _yr smallint;
DEFINE _sess char(4);

SELECT
    DISTINCT
    sess_vw.yr,
    sess_vw.sess,
    sess_vw.sess_sort
FROM
    sess_vw
ORDER BY
    sess_vw.sess_sort DESC
INTO temp tmp_sess WITH NO LOG;

SELECT
    FIRST 1
    tmp_sess.yr,
    tmp_sess.sess
FROM
    tmp_sess
WHERE
    tmp_sess.sess_sort = sess_sort(iYear,sSess)
INTO temp tmp_final WITH NO LOG;

FOREACH cursor1 FOR
    SELECT
        tmp_final.yr,
        tmp_final.sess
    INTO
        _yr,
        _sess
    FROM
         tmp_final
    RETURN _yr, _sess WITH RESUME;
END FOREACH;

DROP TABLE tmp_sess;
DROP TABLE tmp_final;

end procedure

编辑:sess_sort() 进行查找。

我试图将函数重写为一个查询。这里是 next_sess:

SELECT
    FIRST 1
    sess_vw.sess_sort
FROM
    sess_vw
WHERE
    sess_vw.sess_sort > sess_sort(2009,'SP')
ORDER BY
    sess_vw.sess_sort ASC

IBM 的某个人给我发了电子邮件,并建议使用类似这样的方法:

SELECT
    *
FROM
    TABLE(next_sess(2009,'SP'))

但这仍然不起作用。

【问题讨论】:

  • 感谢您的清理和补充信息。
  • 问题:iYear 和 sSess 是程序的输入吗?问题:sess_sort() 过程是做什么的?您似乎想要两行数据?我怀疑它可以简化为一个单一的查询,需要一些小心 - 不需要任何中间临时表。
  • 观察:我很确定临时表是为什么不能在 SQL 语句中使用 curr_sess() 过程的原因 - 额外的表会混淆处理。
  • 反问:实际上,双 RETURN 只是一个错字,不是吗?因为它会返回两次相同的值,然后遍历循环并返回接下来的两行两次。还是您有其他处理方式?

标签: sql stored-procedures informix temp-tables


【解决方案1】:

一种可能性是存储过程。另一个我不确定是否可行的(在 IDS 11.50.FC1 上测试)是:

CREATE PROCEDURE r12() RETURNING INT, INT;
   RETURN 1, 2 WITH RESUME;
   RETURN 2, 3 WITH RESUME;
END PROCEDURE;

CREATE TEMP TABLE t12(c1 INT, c2 INT);

INSERT INTO t12 EXECUTE PROCEDURE r12();

最后一行很重要。


鉴于观察到存储过程无法如上所示执行(因为它包含一些不允许的 SQL 语句),那么您需要以另一种方式使用存储过程 - 由该测试代码说明(有效:首先工作时间,这让我很惊喜):

CREATE TEMP TABLE t12(yr smallint, sess char(4));

CREATE PROCEDURE curr_sess(yearnum SMALLINT, sesscode CHAR(2))
    RETURNING SMALLINT AS yr, CHAR(4) AS sess;
    RETURN yearnum, (sesscode || 'AD') WITH RESUME;
    RETURN yearnum, (sesscode || 'BC') WITH RESUME;
END PROCEDURE;

CREATE PROCEDURE r12(yearnum SMALLINT, sesscode CHAR(2))
    DEFINE yr SMALLINT;
    DEFINE sess CHAR(4);
    FOREACH EXECUTE PROCEDURE curr_sess(yearnum, sesscode) INTO yr, sess
    INSERT INTO t12 VALUES(yr, sess);
    END FOREACH;
END PROCEDURE;

EXECUTE PROCEDURE r12(2009,'SP');

SELECT * from t12;

您可以将临时表的创建合并到存储过程中;您甚至可以安排删除与临时表同名的预先存在的表(使用异常处理)。鉴于您使用的是 IDS 10.00,您会被临时表的固定名称所困扰。尽管(我)不建议使用 11.50 中的动态 SQL 工具在运行时命名临时表,但这是可能的。

请注意,访问临时表的存储过程在重用时会重新优化 - 使用的表与上次不同(因为它是临时表),因此查询计划并没有太大帮助。

【讨论】:

    【解决方案2】:

    这可能是因为“drop table”不是在此上下文中使用的过程中的有效语句吗? http://publib.boulder.ibm.com/infocenter/idshelp/v115/topic/com.ibm.sqls.doc/ids_sqs_1755.htm#ids_sqs_1755

    【讨论】:

    • 我需要删除表,否则函数只能运行一次。
    猜你喜欢
    • 2015-07-05
    • 2012-01-23
    • 1970-01-01
    • 2012-09-05
    • 2015-07-08
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    相关资源
    最近更新 更多