Проблема с оператором UPDATE в хранимой процедуре в базе данных Oracle - PullRequest
0 голосов
/ 21 мая 2010

У меня есть хранимая процедура в базе данных 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 ]

1 голос
/ 21 мая 2010

Почти наверняка значения, которые, по вашему мнению, у вас есть, не являются теми значениями, которые вы на самом деле имеете. Например, если этот оператор возвращает NULL

select przelozony into tmpPrzel from pracownik where id = PRAC_ID;

оператор (4) никогда не будет выполнен. Аналогично, если это возвращает нуль

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 - Ouest TOAD, Allround Automation PL / SQL Developer и Oracle SQL Developer предлагают отладку. Вы можете найти инструкции по отладке в SQL Developer здесь, на OTN .

0 голосов
/ 21 мая 2010

Трудно читать код с чужими именами таблиц и столбцов, поэтому я надеюсь, что я понял это правильно (без обид) - хотя обязательно внимательно прочитайте.

Насколько я понимаю ваш код, вы должны быть в состоянии удалить ваши временные переменные и сделать все в трех последующих операторах обновления (обновление разных строк). Я не знаю, что именно не работает, но если после этого все равно не работает, попробуйте выполнить отдельные операторы 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;
...