Использование переменных в операторе PLSQL SELECT - PullRequest
3 голосов
/ 29 ноября 2010

У меня есть запрос, который запрашивает 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 ]

7 голосов
/ 29 ноября 2010

Вы не можете использовать операторы 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.

4 голосов
/ 29 ноября 2010

Вопрос, на который вы должны ответить: что вы хотите сделать с выбранными данными?

Сатья дал вам один подход - объявить переменные в вашем блоке 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;
...