DB2 - агрегирование с регистром в курсоре

Я пытаюсь создать хранимую процедуру, которая возвращает набор данных с помощью курсора, который содержит несколько агрегатных функций над подзапросами. Запрос работает, когда выполняется как отдельный скрипт, но при помещении его в формат хранимой процедуры с помощью курсора он не работает. При использовании агрегата код работает нормально. При использовании агрегата для оператора 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

Боковое примечание: представленное вами утверждение не требует использования подзапроса. Кроме того, вам не нужно выбирать contract.contract_date, поскольку вы не выводите столбец. Я не знаю, только ли это из ваших попыток получить минимальный пример или ваш запрос действительно так выглядит.

Clockwork-Muse 06.12.2018 18:06

Эй, да, это просто моя попытка получить минимальный пример!

ballBreaker 06.12.2018 18:21
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
394
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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@

Ах, хорошая уловка на FROM, я хотел бы включить это в пример. Не уверен, что вы имеете в виду, говоря об изменении разделителя операторов. Это ваша главная линия, #SET TERMINATOR @?

ballBreaker 06.12.2018 17:14

Это был пример процессора командной строки db2. Он понимает такую ​​директиву. Ваш инструмент, в котором вы запускаете свои операторы, должен иметь собственный способ изменения разделителя операторов по умолчанию.

Mark Barinstein 06.12.2018 17:36

Сработала смена терминатора по умолчанию для базы данных. Спасибо.

ballBreaker 06.12.2018 17:37

Другие вопросы по теме