Использование переменных в операторе PLSQL SELECT
У меня есть запрос, который запрашивает ReportStartDate и ReportEndDate, поэтому я подумал, что буду использовать переменные в PLSQL. Не уверен, что мне здесь не хватает, но я получаю ошибку:
CLEAR;
DECLARE
varReportStartDate Date := to_date('05/01/2010', 'mm/dd/yyyy');
varReportEndDate Date := to_date('05/31/2010', 'mm/dd/yyyy');
BEGIN
SELECT
'Value TYPE',
1 AS CountType1,
2 AS CountType2,
3 AS CountType3
FROM DUAL;
SELECT COUNT (*)
FROM CDR.MSRS_E_INADVCH
WHERE 1=1
AND ReportStartDate = varReportStartDate
AND ReportEndDate = varReportEndDate
;
END;
/
Ошибка:
Error starting at line 2 in command:
Error report:
ORA-06550: line 6, column 5:
PLS-00428: an INTO clause is expected in this SELECT statement
ORA-06550: line 8, column 5:
PLS-00428: an INTO clause is expected in this SELECT statement
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Это происходит как в Toad, так и в SQL Developer.
Как правильно использовать переменные в моем предложении WHERE?
2 ответа
Вы не можете использовать операторы SQL непосредственно в блоке PL/SQL (если вы не используете EXECUTE IMMEDIATE
). Столбцы нужно будет извлекать в переменные (именно об этом вам говорит PL/SQL) PLS-00428: an INTO clause is expected in this SELECT statement
ошибка). Таким образом, вам придется переписать свои заявления, как показано ниже.
SELECT
'Value TYPE',
1 AS CountType1,
2 AS CountType2,
3 AS CountType3
INTO
V_VALUE_TYPE,
V_CountType1,
V_CountType2,
V_CountType3
FROM DUAL;
SELECT COUNT(*)
INTO V_COUNT
FROM CDR.MSRS_E_INADVCH
WHERE 1=1
AND ReportStartDate = varReportStartDate
AND ReportEndDate = varReportEndDate
Обязательно добавьте обработчики исключений, поскольку PL/SQL ожидает, что будет возвращена только 1 строка. Если инструкция не возвращает строк, вы нажмете NO_DATA_FOUND
исключение - и если оператор выбирает слишком много строк, вы нажмете TOO_MANY_ROWS
исключение.
Вопрос, на который вы должны ответить, - что вы хотите сделать с выбранными данными?
Сатья дал вам один подход - объявите переменные в вашем блоке PL/SQL и выберите столбцы INTO
эти переменные. Обратите внимание, что для этого требуется, чтобы инструкция SELECT возвращала ровно одну строку - любые более или менее строки приведут к ошибке. Другой способ - объявить типы коллекций с помощью параметра BULK COLLECT: http://oracletoday.blogspot.com/2005/11/bulk-collect_15.html
Еще один вариант - процедура возвращает курсор. Это полезно в том случае, когда вызывающий код ожидает получить данные, выбранные процедурой:
PROCEDURE GET_MY_REPORT( varReportStartDate in date, varReportEndDate in date, cur out sys_refcursor) is
begin
OPEN cur FOR SELECT *
FROM CDR.MSRS_E_INADVCH
WHERE 1=1
AND ReportStartDate = varReportStartDate
AND ReportEndDate = varReportEndDate;
END GET_MY_REPORT;