【问题标题】:Does the iSeries Access ODBC Driver support multiple statements in pass-through queries..?iSeries Access ODBC 驱动程序是否支持传递查询中的多个语句..?
【发布时间】:2019-09-09 19:29:13
【问题描述】:

当使用iSeries Access ODBC Driver 进行 Microsoft Access 直通查询时,是否可以使用多个语句..?

这是 DB2 for iSeries v7r3m0 和 Access 2007,使用 DBeaver 5.2.5 开发的 SQL。

我之前的所有工作都是使用单个 WITH/SELECT 语句进行查询。但这是我的第一个包含多个语句的脚本。通常我会将其复制到 Access 传递查询中,以使其对我的用户来说很漂亮,但是当我尝试运行这个新查询时,我收到以下错误:

ODBC call failed. [IBM][System i Access ODBC Driver][DB2 for i5/OS]SQL0104 Token ; was not valid. Valid tokens: <END-OF-STATEMENT>

错误很明显:它不喜欢语句终止符,也就是分号。如果我将其删除,则违规标记将变为以下 DECLARE 声明,无限循环。

所以显而易见的问题变成了:这甚至可以在 Access 直通查询中完成吗?

我检查了documentation 是否有任何可能有用的连接字符串关键字,但没有找到。

我的脚本的一般流程如下。这在 DBeaver 中有效,但在 Access 中无效:

CREATE OR REPLACE VARIABLE F_CERTOB.NPS_FIRSTDAY NUMERIC(8)
    DEFAULT ( SELECT (YEAR (CURDATE() - 4 MONTHS) * 10000) + 
                     (MONTH(CURDATE() - 4 MONTHS) * 100) FROM SYSIBM.SYSDUMMY1 ) ;

DECLARE GLOBAL TEMPORARY TABLE SESSION.NPS_DATA0 
    AS  (   WITH    SOMEDATA    AS  (   SELECT      *
                                        FROM        F_CERTOB.DAILYT
                                        WHERE       DACOMP  = '1'
                                        AND         DAIDAT >= (F_CERTOB.NPS_FIRSTDAY+0)
                                        AND         DAIDAT <= (F_CERTOB.NPS_FIRSTDAY+7)
                                    )
            SELECT  *
            FROM    SOMEDATA
        ) WITH DATA WITH REPLACE ;

WITH    SUMBYINVOICE    AS  (   SELECT      DAACCT, DAIDAT, DAINV#, SUM(DAQTY) AS QTY 
                                FROM        SESSION.NPS_DATA0
                                GROUP BY    DAACCT, DAIDAT, DAINV#
                            )

SELECT      *
FROM        SUMBYINVOICE
WHERE       QTY > 0
ORDER BY    DAACCT, DAIDAT, DAINV# ;

DROP TABLE SESSION.NPS_DATA0 ;
DROP VARIABLE F_CERTOB.NPS_FIRSTDAY ;

【问题讨论】:

    标签: db2 db2-400


    【解决方案1】:

    我有理由确定您需要进行单独的 ODBC 调用。

    另外,不同于 Db2(用于 LUW)https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0004239.html Db2 for i 不支持独立的复合 SQL,它们仅用于 SQL 过程。所以你不能只用BEGIN/END 包裹你的代码。

    https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_72/db2/rbafzcompoundstmt.htm

    不过,除非您出于某种性能原因需要 GLOBAL TEMPORARY TABLE,否则您可以在一个语句中编写代码。

    WITH F_CERTOB(NPS_FIRSTDAY) AS ( VALUES
        (YEAR (CURDATE() - 4 MONTHS) * 10000) +  (MONTH(CURDATE() - 4 MONTHS) * 100)
    )
    , NPS_DATA0  AS (
        SELECT *
        FROM   F_CERTOB.DAILYT, F_CERTOB
        WHERE  DACOMP  = '1'
        AND    DAIDAT >= (F_CERTOB.NPS_FIRSTDAY+0)
        AND    DAIDAT <= (F_CERTOB.NPS_FIRSTDAY+7)
    )
    , SUMBYINVOICE AS (
        SELECT      DAACCT, DAIDAT, DAINV#, SUM(DAQTY) AS QTY 
        FROM        NPS_DATA0
        GROUP BY    DAACCT, DAIDAT, DAINV#
    )
    SELECT      *
    FROM        SUMBYINVOICE
    WHERE       QTY > 0
    ORDER BY    DAACCT, DAIDAT, DAINV#
    

    【讨论】:

    • 好吧,我提供的示例非常简化。实际的脚本已经持续了三周,大约有 300 行和 10 个 DGTT。这是一个使用一些旋转列提取约 100 万行的报告。脚本 unpivots/repivots 两次,计算缺失的数据,然后对一些数据进行优先级排序,最后使用EXCEPTION self-join 来查找第二部分中的内容不在第一部分中。作为一个单一的WITH/SELECT,它达到了我在 20 分钟后杀死它的地步。 DGTT进来了,现在只有2分钟..!而且,发现 Access 的痛苦将无法承受。嘘,哈哈。
    • 但我目前正在 Access VBA 中尝试一种解决方法,通过代码生成的动态传递查询将脚本作为服务器端动态 SQL 脚本发送到 DB2 EXEC 语句。问题是 Access ODBC 引擎需要一条语句,所以如果我可以将它作为单个 EXEC 发送,Access 不会关心引号之间的文本,并且希望很乐意接受语句返回的任何行。我们会看看会发生什么。
    • 您应该能够将大部分代码放在一个表函数中。不允许创建变量,但 DGTT 应该在 MODIFIES SQL DATA 表函数中,您可以在 Access 的单个语句中从中选择
    猜你喜欢
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 2013-09-06
    相关资源
    最近更新 更多