2

Oracle データベースに次の PL/SQL ストアド プロシージャがあります。

PROCEDURE MyProcedure (
    p_id IN NUMBER
  , p_date IN DATE
  , p_num IN NUMBER) 
  AS
  BEGIN
    MERGE INTO MY_TABLE mytable
    USING (SELECT
            p_id,
            p_date,
            p_num
          FROM dual) temp
    ON (mytable.myid = temp.p_id AND mytable.mydate = temp.p_date)
  WHEN MATCHED THEN
    UPDATE SET
      DIFFERENCE = temp.p_num,
  WHEN NOT MATCHED THEN
    INSERT VALUES (
      MY_TABLEIDSEQ.NEXTVAL,
      temp.p_id,
      temp.p_date,
      temp.p_num);
END MyProcedure;

MY_TABLE テーブルは次のように定義されています。

CREATE TABLE "MY_DBO"."MY_TABLE" 
   (
     "MYTABLEID" NUMBER(38,0),
     "MYID" NUMBER(38,0),
     "MYDATE" DATE,
     "MYNUM" NUMBER(25,4)
   )

ただし、入力フィールドに有効な値を指定してストアド プロシージャを実行すると、次のエラーが発生します。

ORA-00904: "TEMP"."P_DATE": 識別子が無効です

ORA-06512: "MY_DBO.MY_PKG"、54行目

ORA-06512: 18行目

何が原因なのかわかりません。どんな助けでも大歓迎です。ストアド プロシージャは MY_PKG の 45 行目から始まることに注意してください。

ここで同様の問題を見つけましたが、「デュアル」を「MY_TABLE」に変更する解決策はうまくいかなかったようです。

PS:私はOracleに非常に慣れていません:)

4

2 に答える 2

5

「select from dual」ステートメントでは、ストアド プロシージャの入力パラメータを値として使用しました。実際、Oracle はこれらの列に暗黙的な名前を生成しますが、現時点では予測できません。ただし、そのステートメントで独自の列名/エイリアス名を指定できます。

USING (SELECT
        p_id col_id,
        p_date col_date,
        p_num col_num
      FROM dual) temp

これらの名前は単なる例です。このような場合は、後であいまいさを避けるために一意の名前を使用することを強くお勧めします. マージ ステートメント内の temp.* の使用を、指定したエイリアス名に置き換える必要があります。

于 2012-06-13T17:15:04.503 に答える
0

Juergen Harteltがすでに回答しているので、これは実際にはあなたの質問に答えませんが、それはあなたにいくつかのより多くの情報を提供します。

ここでは1つの行のみを挿入または更新しているため、別のオプションとして、との使用を中止し、代わりにとMERGEの組み合わせを使用することもできます。INSERTUPDATE

あなたの場合、あなたは使用します

PROCEDURE MyProcedure (
    p_id IN NUMBER
  , p_date IN DATE
  , p_num IN NUMBER) 
  AS
  BEGIN
    Update MY_TABLE mytable
    Set MYNUM = p_num
    Where mytable.MYID = p_id AND mytable.MYDATE = p_date;

    If SQL%ROWCOUNT = 0 then
      INSERT INTO MY_TABLE mytable 
      Values (MY_TABLEIDSEQ.NEXTVAL,
      temp.p_id,
      temp.p_date,
      temp.p_num);
    END IF;

END MyProcedure;

また、この問題を解決するためのオプションの完全なメニューが提供されるため、「UPSERTの方法」という質問を確認する価値があるかもしれません。

于 2012-06-13T17:46:19.027 に答える