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


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 @?
Это был пример процессора командной строки db2. Он понимает такую директиву. Ваш инструмент, в котором вы запускаете свои операторы, должен иметь собственный способ изменения разделителя операторов по умолчанию.
Сработала смена терминатора по умолчанию для базы данных. Спасибо.
Боковое примечание: представленное вами утверждение не требует использования подзапроса. Кроме того, вам не нужно выбирать
contract.contract_date, поскольку вы не выводите столбец. Я не знаю, только ли это из ваших попыток получить минимальный пример или ваш запрос действительно так выглядит.