1

そのため、インストーラーがデータベースに接続してテーブルを作成し、それらにデータを入力するインストーラーに取り組んでいます。特定のテーブルに行を追加しようとする場合を除いて、これのすべての側面が正しく機能します。

declare
  retVal INTEGER;
  rptID INTEGER;
  catID INTEGER;
  wsID INTEGER;
  paramID INTEGER;
  dtID INTEGER;
begin

  select PK into catID from RPT_CATEGORY where KEYVALUE = 'ProductivityReportsCategory';
  select PK into rptID from RPT_REPORT where KEYVALUE = 'ProductivitySummaryReport2';
  select PK into wsID from RPT_WEBSVC where KEYVALUE = 'NotApplicable' and category_fk = catID;

データベースに入力する select ステートメントは次のようになります。

  select PK into wsID from RPT_WEBSVC where KEYVALUE = 'GetMachineNameList' and category_fk = catID;
  paramID := RPT_CONFIGURATION.ADD_PARAMETER( rptID, wsID, dtID, 'Machine', 'parameters.GetProductivityDataSet3.inserterid', 4, NULL, NULL, NULL, 0, 0, 0, 'Y', 'Y', 'N', 'N', 'Y' );

このように構成された 13 個の select ステートメントがあります (それらはすべて類似しており、唯一の違いはテーブルに格納される値だけであるため、追加しません)。

私の問題は、インストーラーを実行すると、完了時にログに次のエラーが表示されることです。

ORA-01422: exact fetch returns more than requested number of rows 
ORA-06512: at line 30

私が知りたいのは、このエラーが発生する正確な理由と、このエラーを修正する手段は何ですか?

このトピックについていくつかの調査を行ったところ、これが私の検索の共通のテーマであることがわかりました。

1.コードにバグがあり、開発者は、複数の行が返される可能性があることに気づきませんでした。

2.API を使用せずにデータがハッキングされたため、検証が破られた。

3.ソフトウェアは問題ありません。ユーザーが行ったことは問題ありませんが、2 つの並行更新が同時に発生し、どちらも他方が行ったコミットされていない変更を確認できませんでした。したがって、正しく検証されませんでした。

#2ではないことは確かですが、他の2つの理由が正確に何を意味するのか、またはそれらを修正する方法がよくわかりません。

どんな助けや提案も大歓迎です。

ありがとう

4

3 に答える 3

6

ORA-01422: 正確なフェッチは、要求された数よりも多くの行を返します

この例外は、SELECT INTO ステートメントが実行され、複数の行が検出されるたびに発生します。SELECT INTO ステートメントは、正確に 1 つの行を検索することを想定しています。それ以外の場合は、例外が発生します。

あなたの例では:

select PK into wsID from RPT_WEBSVC
where KEYVALUE = 'GetMachineNameList'
and category_fk = catID;

(KEYVALUE, CATEGORY_FK) の組み合わせごとに 1 つの行しかないように見えますが、実際にはそうではありません。1つしかない場合、テーブルはそれらの列に一意の制約を持つ必要があります:

alter table RPT_WEBSVC add constraint RPT_WEBSVC_UK
    unique (KEYVALUE, CATEGORY_FK);

これにより、誰か (または何らかのプロセス) が同じ行を再度追加するのを防ぐことができます。もちろん、その制約を追加する前に、テーブルの重複を排除する必要があります。

于 2011-08-15T16:21:05.237 に答える
4

これは、「SELECT INTO」ステートメントが複数の行を返したことを意味します。このステートメントでは、クエリによって 1 行だけが返される必要があります。それ以外の場合は、カーソル ループを使用して行を処理する必要があります。

SQL*Plus の select ステートメントを調べて、問題のあるクエリがどれかを確認してください。

于 2011-08-15T16:17:35.457 に答える
0

ここで問題の原因として番号 1 を見てみましょう。すべてのステートメントを確認しないと、これらのクエリのどれが複数の行を返す可能性があるかを判断するのは困難ですが、データベース スキーマは変更される可能性があるため、ここから始めるのが良いでしょう。 ...

于 2011-08-15T16:19:24.520 に答える