Дублирование процедуры записи INSERT

У меня проблема с процедурой mu, которая вставляет повторяющуюся последнюю запись в таблицу.

пример, когда я вставил INSERT..... 'AAA', я получил строки в таблице 'AAA' и 'AAA'

Вместо того, чтобы поместить DBMS()... в код, я получил две записи. Я использую триггер и последовательность для идентификатора столбца в HistoriaDismissDate, но они в хорошем состоянии. Я проверяю, сбросил ли я триггер и последовательность, и это та же ситуация.

Я также использую viewDate, но это представление получает ОДНУ запись, а не две.

мой код

CREATE OR REPLACE PROCEDURE ChangeDismissDate
IS

          v_id VARCHAR2(11);
          v_dateBhd DATE := TO_DATE('20491231','yyyymmdd');
          v_dateDismiss DATE := TO_DATE('20491231','yyyymmdd');
          v_login VARCHAR2(50);
          last_id NUMBER :=0;

        CURSOR cur IS
                select EMP_NO, LOGIN, ODEJSCIE_BHD, ODEJSCIE_OLD FROM viewDate;

        BEGIN
                       OPEN cur;
                           LOOP
                                FETCH cur INTO v_id,v_login,v_dateBhd,v_dateDismiss;
                                  DBMS_OUTPUT.put_line(v_id || ' ' || v_login || ' ' || v_dateBhd || ' ' || v_dateDismiss);
                                 UPDATE employee_tab SET DISMISS_DATE = v_dateBhd WHERE EMP_NO = v_id;
                                 COMMIT;

                                 INSERT INTO HistoriaDismissDate(CUSTOMER_ID,LOGIN, DATE_CHANGE, DATE_BHD, DATE_DISMISS)
                                 VALUES(v_id,v_login, sysdate, v_dateBhd, v_dateDismiss);
                                 COMMIT;

                           EXIT WHEN cur%NOTFOUND;
                           END LOOP;
                           CLOSE cur;


    EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
        DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
    WHEN OTHERS
    THEN
        DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
    END;
/

person Przemek    schedule 21.11.2012    source источник
comment
поставить EXIT WHEN cur%NOTFOUND; сразу после FETCH cur INTO   -  person Nick Krasnov    schedule 21.11.2012


Ответы (1)


2 совета по исходному коду:

1) курсор - это очень старый метод программирования на PL/SQL. Лучше использовать конструкцию FOR... LOOP. Это чище и менее подвержено ошибкам! Увидеть как это работает:

CREATE OR REPLACE PROCEDURE ChangeDismissDate IS
BEGIN
  for cur in (select EMP_NO, LOGIN, ODEJSCIE_BHD, ODEJSCIE_OLD FROM viewDate) loop

     DBMS_OUTPUT.put_line(cur.EMP_NO || ' ' || cur.login || ' ' || cur.ODEJSCIE_BHD || ' ' || cur.ODEJSCIE_OLD);
     UPDATE employee_tab 
        SET DISMISS_DATE = cur.ODEJSCIE_BHD
      WHERE EMP_NO = cur.EMP_NO;

     INSERT INTO HistoriaDismissDate
       ( CUSTOMER_ID,LOGIN, DATE_CHANGE, DATE_BHD, DATE_DISMISS )
     VALUES
       ( cur.EMP_NO, cur.LOGIN, sysdate, cur.ODEJSCIE_BHD, cur.ODEJSCIE_OLD, );
  end loop;
end;
/

2) Никогда, я имею в виду никогда не помещать фиксацию внутри вашей процедуры. Фиксация должна выполняться в вызывающем блоке или в клиентском приложении. Когда вы помещаете фиксацию внутри своей процедуры, вы упускаете возможность отката после ее запуска, и другие процедуры не могут ее вызвать, если хотят контролировать поток транзакций.

person Josir    schedule 07.12.2012