1

指定されたパラメーター(日付)がテーブル内の既存の日付のいずれかにあるかどうかを確認するプロシージャを作成しようとしています。そうでない場合は、新しい行を挿入します。

CREATE OR REPLACE PROCEDURE test(date1 IN DATE, date2 IN DATE) AS 
  ddate1 DATE;
  ddate2 DATE;
  quer VARCHAR2(50);
BEGIN 
  SELECT fdate, tdate INTO ddate1, ddate2 FROM dataHolder; 
  IF (ddate1 < date1) AND (ddate2 > date2) THEN
    quer := 'invalid'; 
  ELSE 
    INSERT INTO dataHolder VALUES (date1, date2);
    quer := 'success';
  END IF; 
  DBMS_OUTPUT.PUT_LINE(quer); 
END;
/

私はこのようなことを試しましたが、実行すると次のエラーが発生します:

ORA-01422: exact fetch returns more than requested number of rows
4

3 に答える 3

1

単一値の変数にフェッチしているため、select ステートメントは複数のレコードをフェッチしますが、コードは 1 つしか期待していません。BULK COLLECT を使用してすべての日付を収集して日付のコレクションにすることもできますが、以下のコードで改善できると思います。

CREATE OR REPLACE PROCEDURE test(date1 IN DATE, date2 IN DATE) AS 
  ddate1 DATE;
  ddate2 DATE;
  invalidRecords NUMBER := 0;
  quer VARCHAR2(50);
BEGIN
   SELECT COUNT(1) INTO invalidRecords FROM dataHolder WHERE fdate < date1 AND tdate > date2; 

   IF (invalidRecords > 0) THEN
     quer := 'invalid'; 
   ELSE
     INSERT INTO dataHolder VALUES (date1, date2);
     quer := 'success';
   END IF;

   DBMS_OUTPUT.PUT_LINE(quer); 
END;
/

COUNT(1) は常に 1 つのレコードのみを返すため、ORA-01422 エラーがスローされることはありません。また、常にデータが返されるため、無効なレコードがない場合は値 0 がフェッチされるため、NO_DATA_FOUND について心配する必要はありません。

于 2012-12-20T20:52:05.347 に答える
1

select ステートメントが複数のレコードを返すため、そのエラーが発生しています。プロセスを簡素化するには、mergeステートメントを使用して、手順を次のように書き換えます。

CREATE OR REPLACE PROCEDURE test(date1 IN DATE, date2 IN DATE) AS
BEGIN
  merge into Dataholder dh
  using dual
     on ((date1 < dh.fdate) and (date2 < dh.tdate))
  when not matched then
    insert (dh.fdate, dh.tdate)
      values(date1, date2);
  if sql%rowcount > 0
  then
    dbms_output.put_line('success');
  else
    dbms_output.put_line('invalid');
  end if;
END; 
于 2012-12-20T20:51:48.727 に答える
0

Nuno Guerreiroの答えのいくつかの小さな最適化

SELECT COUNT(1) INTO invalidRecords 
FROM dual 
WHERE exists 
  (SELECT 1 FROM dataHolder WHERE fdate < date1 AND tdate > date2);

カウントしないようにすることができます。

于 2012-12-21T06:43:36.957 に答える