Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using variables in PLSQL SELECT statement

I have a query that queries on ReportStartDate and ReportEndDate so I thought I would use variables in PLSQL. Not sure what I am missing here, but I get an error:

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;
/

The Error is:

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:

This happens in Toad as well as in SQL Developer.

What is the proper way of using the variables in my WHERE clause?

like image 546
Raj More Avatar asked Dec 21 '22 20:12

Raj More


2 Answers

You cannot use SQL statements directly in a PL/SQL block ( unless you use EXECUTE IMMEDIATE). The columns will need to be fetched into variables ( which is what PL/SQL is telling you with PLS-00428: an INTO clause is expected in this SELECT statement error). So you'll have to rewrite your statements as below.

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 

Be sure to add Exception Handlers, since PL/SQL expects only 1 row to be returned. If the statement returns no rows, you'll hit a NO_DATA_FOUND exception - and if the statement fetches too many rows, you'll hit a TOO_MANY_ROWS exception.

like image 180
Sathyajith Bhat Avatar answered Jan 04 '23 18:01

Sathyajith Bhat


The question you have to answer is what do you want to do with the data that has been selected?

Sathya gave you one approach - declare variables in your PL/SQL block and select the columns INTO those variables. Note that this requires that the SELECT statement returns exactly one row - any more or less rows will throw an error. Another way is to declare collection types using the BULK COLLECT option: http://oracletoday.blogspot.com/2005/11/bulk-collect_15.html

Yet another option is to have the procedure return a cursor. This is useful in the case where the calling code expects to be able to fetch the data that the procedure has selected:

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;
like image 32
Dan Avatar answered Jan 04 '23 19:01

Dan