Oracle数据库中存储过程中的UPDATE语句出现问题

时间:2010-05-20 20:24:18

标签: oracle stored-procedures plsql procedure

我在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)”的行中的更多语句可以正常工作。

我不知道如何修复它。提前感谢您的帮助。

2 个答案:

答案 0 :(得分: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)永远不会被执行。要检查这一点,您需要在代码中放置一些trace语句,或者通过调试器运行它。

将跟踪放入程序的最快方法是使用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 here on OTN中找到有关调试的说明。

答案 1 :(得分:0)

使用外表和列名读取代码很困难,所以我希望我做对了(没有冒犯) - 请务必仔细查看。

据我了解您的代码,您应该能够删除临时变量,并在三个后续更新语句中执行所有操作(更新不同的行)。我不知道究竟什么不起作用,但如果它仍然无法工作,请尝试手动执行单个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,请按pensja增加15,但不要超过5000

IF(PR_PRZELOZONY > 0) THEN 
    UPDATE pracownik
    SET pensja = GREATEST( pensja + 150, 5000 )
    WHERE id = pr_przelozony;
END IF;