2

この質問は私の前の質問に関連しています。

PROC_YEARLYACTIVELIST2指定した年にアクティブなすべてのレコードを表示する procedure( ) があります。
の以前の内容を削除しTBLACTIVELISTYEARLY2、結果を挿入しPROC_YEARLYACTIVELIST2ます。を実行し、 からすべてのレコードを選択してに入れ、Crystal Report のテーブルを返す

関数を作成しました。 以下はコードの一部です。TBLACTIVELISTYEARLY2TBLACTIVELISTYEARLYCURSOR C_IH


宣言する
  CURSOR C_IH IS SELECT * FROM tblActiveListYearly2;

  ctr INT;
  私は番号です。  
  currDeploymentComputer COL_TYPE_DEPLOYMENT_COMPUTER := COL_TYPE_DEPLOYMENT_COMPUTER NULL);
  R_IH C_IH%ROWTYPE;

 始める
 PROC_YEARLYACTIVELIST2(in_year);

  OPEN C_IH;
   私:= 0;
    ループ (....)

関数を次のように呼び出そうとしました

SELECT GETDEPLOYMENT_COMPUTER('2012') from dual;

そして、ORA-14551エラーがあります

ORA-14551: cannot perform a DML operation inside a query 
ORA-06512: at "NPLS.PROC_YEARLYACTIVELIST2", line 12
ORA-06512: at "NPLS.GETDEPLOYMENT_COMPUTER", line 3

それを検索したところ、INSERTUPDATEまたはDELETEとの競合が原因であることがわかりましたDUAL

テーブルを返す関数でプロシージャを実行する他の方法はありますか?

ありがとう!

4

3 に答える 3

2

いいえ; 非常に正当な理由により、SELECT ステートメントで DML を実行することはできません。

データベース内のデータを変更しようとしており、Oracle はデータの読み取り一貫性のあるビューを必要としています。

あなたがしていることは非常に不必要に聞こえます。あなたは3ステップのプロセスを持っています:

  1. テーブルから一部のデータを削除する
  2. そのテーブルに新しいデータを挿入します
  3. テーブルからデータを選択します。

必要なデータを選択するだけではどうですか。それははるかに速くなりますか?データを前処理する必要がある場合は、データの選択とは非同期にこれを行う手順を使用できます。

Crystal Reports については何も知りませんが、PL/SQL ブロックでこれを行うこともできます。

declare
   l_getdeployment my_variable_type;
begin
   l_getdeployment := GETDEPLOYMENT_COMPUTER('2012');
end;
/
于 2013-02-12T08:22:24.897 に答える
1

DML の変更とレポート部分を分離する必要があると思います。データ変更を行うプロシージャは、レポート関数呼び出しの外で呼び出す必要があります...

于 2013-02-12T06:32:08.003 に答える
0

これはとても複雑でした。
テーブルからクリスタルレポートへのレコードを取得したいという理由で、選択したものをテーブルに入れます。ここで、プロシージャのロジックを関数に配置し、それを に配置し、それを返し、次のクエリを使用して関数を呼び出す

ことができることに気付きました。SYS_REFCURSOR

SELECT * FROM TABLE(GETDEPLOYMENT_COMPUTER('2012'));

とにかく、応答して助けてくれた人々に感謝します。:)

于 2013-02-13T01:50:07.327 に答える