4

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 句で変数を使用する適切な方法は何ですか?

4

2 に答える 2

7

PL/SQLブロックで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例外が発生します。

于 2010-11-29T15:21:47.407 に答える
4

答えなければならない質問は、選択したデータをどうしたいかということです。

INTOSathya は、PL/SQL ブロックで変数を宣言し、それらの変数の列を選択するという 1 つのアプローチを提供しました。これには、SELECT ステートメントが正確に 1 つの行を返す必要があることに注意してください。これより多くても少なくても、エラーがスローされます。もう 1 つの方法は、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;
于 2010-11-29T16:30:46.533 に答える