DB2-聚集带有光标的大小写

时间:2018-12-06 15:48:28

标签: sql db2 cursor case aggregate-functions

我正在尝试创建一个存储过程,该过程使用游标返回一个数据集,该数据集包含子查询上的多个聚合函数。该查询在作为独立脚本执行时有效,但是在使用游标将其置于存储过程格式时不起作用。使用聚合时,代码运行良好。在case语句上使用聚合时,将无法创建存储过程。

输入表格数据:

Province |  Contract Date
---------------------------
Ontario  |  June 11th, 2017
Ontario  |  June 21st, 2017
Quebec   |  July 12th, 2017

查询:

DECLARE C2 CURSOR WITH HOLD WITH RETURN TO CALLER FOR
SELECT 
    count(province) as province_total
    FROM (
       SELECT 
          contract.province,
          contract.contract_date
       WHERE contract.CON_CONTRACT_DATE >='2015-01-01' 
       AND contract.CON_CONTRACT_DATE < '2018-11-01'
    );

返回:

Province_Total |  
----------------
3              |  

因此,这给了我省的总数。我正在尝试统计一个特定省发生了多少次。我正在使用以下查询:

CREATE PROCEDURE test
DYNAMIC RESULT SETS 1  
BEGIN

DECLARE C1 CURSOR WITH RETURN TO CALLER FOR
SELECT 
    count(province) as province_total,
    sum(case province when 'Ontario' then 1.0 else 0.0 end) as ontario_total,
    sum(case province when 'Quebec' then 1.0 else 0.0 end) as quebec_total
    FROM (
       SELECT 
          contract.province,
          contract.contract_date
       FROM dbo.contract as contract
       WHERE contract.CON_CONTRACT_DATE >='2015-01-01' 
       AND contract.CON_CONTRACT_DATE < '2018-11-01'
    );
   OPEN C1;
   END

我应该得到的是:

Province_Total | Ontario_Total | Quebec_Total
----------------------------------------------
3              | 2             | 1

但是在尝试创建过程时出现错误。具体来说:

SQL Error [42601]: An unexpected token "END-OF-STATEMENT" was found following "".  Expected tokens may include:  "".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.13.80

根据我在DB2上遇到此错误消息的经验,当语法上出现“错误”时,将抛出该错误消息。语句结尾字符“;”否则将被识别。

有什么方法可以在DB2中获得所需的结果吗?通常需要使用游标,因为我需要结果集返回

任何建议将不胜感激。谢谢。

编辑:使用DB2 9.5

1 个答案:

答案 0 :(得分:1)

2问题。

您必须将示例中的默认语句分隔符更改为一些新的分隔符,如示例中所示。

您的示例中缺少FROM子句。

如果从DB2 CLP运行它,应该是这样的。

--#SET TERMINATOR @
CREATE PROCEDURE test
DYNAMIC RESULT SETS 1  
BEGIN

DECLARE C1 CURSOR WITH RETURN TO CALLER FOR
SELECT 
    count(province) as province_total,
    sum(case province when 'Ontario' then 1.0 else 0.0 end) as ontario_total,
    sum(case province when 'Quebec' then 1.0 else 0.0 end) as quebec_total
    FROM (
       SELECT 
          contract.province,
          contract.contract_date
    FROM MY_TABLE
       WHERE contract.CON_CONTRACT_DATE >='2015-01-01' 
       AND contract.CON_CONTRACT_DATE < '2018-11-01'
    );
   OPEN C1;
   END@