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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2877517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 20:40:17  来源:igfitidea点击:

Problem with UPDATE statement in stored-procedure in Oracle Database

oraclestored-proceduresplsqlprocedure

提问by MKP

I have stored-procedure in Oracle database like this:

我在 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;

where przelozony and pensja are columns in pracownik table.

其中 przelozony 和 pensja 是 pracownik 表中的列。

And I have problem that when running procedure with parameters that provide that line marked with "(1)" (there is the same problem with line marked with "(4)") should be executed that update statement don't have any effect. What's more statements in lines marked with "(2)" and "(3)" works fine.

而且我遇到的问题是,当运行带有提供标有“(1)”行的参数的过程时(标有“(4)”的行存在相同的问题),应该执行更新语句没有任何效果。标有“(2)”和“(3)”的行中的更多语句工作正常。

I have no ideas how to fix it. Thank you in advance for your help.

我不知道如何解决它。预先感谢您的帮助。

采纳答案by Peter Lang

It's difficult to read code with foreign table and column names, so I hope I got it right (no offense) - make sure to review carefully though.

阅读带有外部表名和列名的代码很困难,所以我希望我做对了(没有冒犯) - 不过一定要仔细检查。

As far as I understand your code, you should be able to remove your temporary variables and do everything in three subsequent update statements (updating different rows). I don't know what exactly does not work, but if it still does not work after, try to execute the single SQL statements manually and check the results.

据我了解您的代码,您应该能够删除临时变量并在三个后续更新语句中执行所有操作(更新不同的行)。我不知道究竟是什么不起作用,但如果它仍然不起作用,请尝试手动执行单个 SQL 语句并检查结果。



Update pracownik, reduce pensja by 150but not below 1000where id = przelozony (prac_id)

更新pracownik,将 pensja 减少150但不低于1000where id = przelozony (prac_id)

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

Update pracownik, set some values, and przelozony.

更新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;

Update pracownikif PR_PRZELOZONY > 0, increase pensjaby 15, but not above 5000.

更新pracownik如果PR_PRZELOZONY > 0,增加pensja15,但上面没有5000

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

回答by APC

Almost certainly the values you think you have are not the values you actually have. For instance, if this statement returns a NULL

几乎可以肯定,您认为自己拥有的价值观并不是您实际拥有的价值观。例如,如果此语句返回 NULL

select przelozony into tmpPrzel from pracownik where id = PRAC_ID;

statement (4) will never be executed. Likewise if this returns a null

语句 (4) 永远不会被执行。同样,如果这返回空值

select pensja into tmpPensja from pracownik where id = PR_PRZELOZONY;

statement (1) will never be executed. To check this you need to put some trace statements in your code, or run it through a debugger.

语句 (1) 永远不会被执行。要检查这一点,您需要在代码中放置一些跟踪语句,或通过调试器运行它。

The quickest way of putting trace into a program is to use DBMS_OUTPUT.PUT_LINE and run the stored procedure in a client like SQL*Plus (or use an IDE).

将跟踪放入程序的最快方法是使用 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 );
    ...

etc.

等等。

All the most popular PL/SQL IDEs - Ouest TOAD, Allround Automation PL/SQL Developer and Oracle SQL Developer offer debugging. You can find instructions for debugging in SQL Developer here on OTN.

所有最流行的 PL/SQL IDE - Ouest TOAD、Allround Automation PL/SQL Developer 和 Oracle SQL Developer 都提供调试。您可以在 OTN 上的此处找到有关 SQL Developer 中调试的说明。