0

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

create or replace
PROCEDURE EDYTUJ_PRACOWNIKA
  (PR_IMIE IN VARCHAR2, PR_NAZWISKO IN VARCHAR2, PR_PENSJA IN FLOAT,
  PR_PRZELOZONY IN NUMBER, PR_ODDZIAL IN NUMBER, PRAC_ID IN NUMBER)
AS
tmpPensja FLOAT := 0;
tmpPrzel NUMBER := 0;
BEGIN
  select przelozony into tmpPrzel from pracownik where id = PRAC_ID;
  IF(tmpPrzel IS NOT NULL) THEN
    select pensja into tmpPensja from pracownik where id = tmpPrzel;
    IF(tmpPensja < 1150) THEN
      UPDATE PRACOWNIK SET pensja = 1000 WHERE id = tmpPrzel;
    ELSE
      UPDATE PRACOWNIK SET pensja = pensja - 150 WHERE id = tmpPrzel; (4)
    END IF;
  END IF;

  IF(PR_PRZELOZONY > 0) THEN 
    UPDATE PRACOWNIK SET imie = PR_IMIE, nazwisko = PR_NAZWISKO, pensja = PR_PENSJA, przelozony = PR_PRZELOZONY,
      oddzial = PR_ODDZIAL WHERE id = PRAC_ID; (2)
    select pensja into tmpPensja from pracownik where id = PR_PRZELOZONY;

    IF(tmpPensja > 4850) THEN
      UPDATE PRACOWNIK SET pensja = 5000 WHERE id = PR_PRZELOZONY;
    ELSE
      UPDATE PRACOWNIK SET pensja = pensja + 150 WHERE id = PR_PRZELOZONY; (1)
    END IF;
  ELSE
    UPDATE PRACOWNIK SET imie = PR_IMIE, nazwisko = PR_NAZWISKO, pensja = PR_PENSJA, przelozony = NULL,
      oddzial = PR_ODDZIAL WHERE ID = PRAC_ID; (3)
  END IF;
END;

ここで、przelozony と pensja は pracownik テーブルの列です。

そして、「(1)」でマークされた行(「(4)」でマークされた行にも同じ問題があります)を提供するパラメーターを使用してプロシージャを実行すると、更新ステートメントが実行されないという問題があります効果。さらに、「(2)」および「(3)」でマークされた行のステートメントは正常に機能します。

修正方法がわかりません。よろしくお願いいたします。

4

2 に答える 2

1

自分が持っていると思っている価値観が、実際に持っている価値観ではないことはほぼ確実です。たとえば、このステートメントが NULL を返す場合

select przelozony into tmpPrzel from pracownik where id = PRAC_ID;

ステートメント (4) は決して実行されません。同様に、これが null を返す場合

select pensja into tmpPensja from pracownik where id = PR_PRZELOZONY;

ステートメント (1) は決して実行されません。これを確認するには、コードにいくつかのトレース ステートメントを入れるか、デバッガーで実行する必要があります。

トレースをプログラムに挿入する最も簡単な方法は、DBMS_OUTPUT.PUT_LINE を使用し、ストアド プロシージャを SQL*Plus などのクライアントで (または IDE を使用して) 実行することです。

select przelozony into tmpPrzel from pracownik where id = PRAC_ID;
dbms_output.put_line('PRAC_ID ='|| PRAC_ID ||':: tmpPrze='|| tmpPrze );
IF(tmpPrzel IS NOT NULL) THEN
    select pensja into tmpPensja from pracownik where id = tmpPrzel;
    dbms_output.put_line('tmpPrzel IS NOT NULL:: tmpPensja='|| tmpPensja );
    ...

最も人気のあるすべての PL/SQL IDE である Ouest TOAD、Allround Automation PL/SQL Developer、および Oracle SQL Developer は、デバッグを提供します。SQL Developerでのデバッグの手順は、OTNでここにあります。

于 2010-05-20T22:41:10.677 に答える
0

外部のテーブル名と列名を含むコードを読むのは難しいので、正しく理解できていることを願っています (悪気はありません) - ただし、注意深く確認してください。

私があなたのコードを理解している限り、一時変数を削除し、後続の 3 つの更新ステートメント (異なる行の更新) ですべてを実行できるはずです。何がうまくいかないのか正確にはわかりませんが、それでもうまくいかない場合は、単一の SQL ステートメントを手動で実行して結果を確認してください。


更新pracownik、pensja を減らし150ます1000が、id = przelozony (prac_id)

UPDATE pracownik
SET pensja = LEAST( pensja-150, 1000 )
WHERE id = ( SELECT przelozony FROM pracownik where id = PRAC_ID );

を更新pracownikし、いくつかの値を設定しますprzelozony

UPDATE pracownik
SET imie = PR_IMIE,
    nazwisko = PR_NAZWISKO,
    pensja = PR_PENSJA,
    przelozony = CASE WHEN PR_PRZELOZONY > 0 THEN PR_PRZELOZONY ELSE NULL END,
    oddzial = PR_ODDZIAL
WHERE id = PRAC_ID;

pracownikの場合は更新し、 だけPR_PRZELOZONY > 0増やしますが、 を超えません。pensja155000

IF(PR_PRZELOZONY > 0) THEN 
    UPDATE pracownik
    SET pensja = GREATEST( pensja + 150, 5000 )
    WHERE id = pr_przelozony;
END IF;
于 2010-05-20T20:57:26.137 に答える