2017-02-07 26 views
0

Некоторые изменения в хранимых процедурах, похоже, не ... uhm ... подтверждены Oracle.Некоторые изменения в хранимой процедуре, похоже, не вступают в силу

Например, я добавил параметр в свою процедуру, перекомпилировал его (в DataGrip-talk) и вызвал его из моего кода. Казалось, что он работает, он принимает новый параметр.

Однако я допустил ошибку, указав ей тип «INT», который не является допустимым типом. Я попытался изменить его на «NUMBER», но поведение по-прежнему остается прежним.

Позвольте мне объяснить. Я добавил первичный ключ к таблице (эй, не судите меня, я вошел после факта, я никогда не создавал бы таблицу без первичного ключа) и добавил ее как параметр к хранимой процедуре, которую предыдущий программист сделал либо вставку, либо обновление. Однако значение, которое они использовали в качестве уникального ограничения, оказалось, что оно обязательно НЕ является уникальным, поэтому я добавил первичный ключ.

Однако каждый раз, когда я запускал процедуру, вместо добавления новой строки, поскольку одно поле имело то же значение, оно обновляло бы существующую строку. Это как если бы никогда не распознавать параметр ID, поскольку это новая строка. См. Код ниже для уточнения.

К счастью для меня, сотрудник столкнулся с этой проблемой раньше и сообщил мне, что если мне нужно будет скопировать определение процедуры, переименуйте ее и скопируйте и запустите, это сработает. Так я и сделал. И это так.

Итак, кто-нибудь знает, почему некоторые изменения хранимых процедур распознаются Oracle, а некоторые изменения нет? Если это связано с кешированием или тем, как Oracle хранит эти процедуры? Есть ли команда, которую я могу запустить, чтобы «обновить» хранение процедур, поскольку она автоматически не делает этого?

Спасибо всем!

Вот три варианта процедуры: оригинал, мое первое изменение, которое получило признание, и мое второе изменение, которое не было. Обратите внимание на параметр v_ID

Оригинал:

create PROCEDURE  proc_name_removed_for_privacy 
    ( v_Month_Year IN VARCHAR2, 
    v_Title IN VARCHAR2, 
    v_UserID IN VARCHAR2, 
    v_Visible IN CHAR 
    ) 
    as 

v_IsNew CHAR(1):= 'T'; 

BEGIN 
    SELECT DECODE(COUNT(Month_Year),0,'T','F') INTO v_IsNew 
     FROM table_name_removed_for_privacy 
    WHERE Month_Year = v_Month_Year; 

     IF UPPER(TRIM(v_IsNew)) = 'T' THEN 
     INSERT INTO table_name_removed_for_privacy 
     (
      Month_Year, 
      Title, 
      created_by, 
      date_added, 
      modified_by, 
      date_modified, 
      visible 
     ) 
     VALUES(v_Month_Year,v_Title,v_UserID,SYSDATE,v_UserID,SYSDATE,v_Visible); 
     COMMIT; 
    ELSE 
     UPDATE table_name_removed_for_privacy 
      SET Title = v_Title, 
       modified_by = v_UserID, 
       date_modified = SYSDATE, 
       visible = v_Visible 
     WHERE Month_Year = v_Month_Year; 
     COMMIT; 

    END IF; 

END; -- Procedure 

Второе:

create PROCEDURE  proc_name_removed_for_privacy 
(
    v_Month_Year IN VARCHAR2, 
    v_Title IN VARCHAR2, 
    v_UserID IN VARCHAR2, 
    v_Visible IN CHAR, 
    v_ID IN INT DEFAULT -1 
) as 

BEGIN 
    IF v_ID = -1 THEN 
     INSERT INTO table_name_removed_for_privacy 
     (
      Month_Year, 
      Title, 
      created_by, 
      date_added, 
      modified_by, 
      date_modified, 
      visible 
     ) 
     VALUES(v_Month_Year,v_Title,v_UserID,SYSDATE,v_UserID,SYSDATE,v_Visible); 
     COMMIT; 
    ELSE 
     UPDATE table_name_removed_for_privacy 
     SET Title = v_Title, 
      modified_by = v_UserID, 
      date_modified = SYSDATE, 
      visible = v_Visible 
     WHERE ID = v_ID; 
     COMMIT; 
    END IF; 
END; -- Procedure 

Третье:

create PROCEDURE  proc_name_removed_for_privacy 
(
    v_Month_Year IN VARCHAR2, 
    v_Title IN VARCHAR2, 
    v_UserID IN VARCHAR2, 
    v_Visible IN CHAR, 
    v_ID IN NUMBER DEFAULT -1 
) as 

BEGIN 
    IF v_ID = -1 THEN 
     INSERT INTO table_name_removed_for_privacy 
     (
      Month_Year, 
      Title, 
      created_by, 
      date_added, 
      modified_by, 
      date_modified, 
      visible 
     ) 
     VALUES(v_Month_Year,v_Title,v_UserID,SYSDATE,v_UserID,SYSDATE,v_Visible); 
     COMMIT; 
    ELSE 
     UPDATE table_name_removed_for_privacy 
     SET Title = v_Title, 
      modified_by = v_UserID, 
      date_modified = SYSDATE, 
      visible = v_Visible 
     WHERE ID = v_ID; 
     COMMIT; 
    END IF; 
END; -- Procedure 
+0

На самом деле я просто понял, что, основываясь на поведении, которое я описал, я бы предположил, что ни одно из изменений, которые я сделал, не было признано Oracle вообще, поэтому оно все еще обновляется на основе существующего v_Month_Year значение, как показано в исходном proc. WTF. – MystikDan

+0

'INT' - это просто подтип' NUMBER'. [oracle doc] (https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/datatypes.htm) –

+0

* скопируйте определение процедуры, переименуйте его и скопируйте *. Чтобы добавить параметр, используйте ALTER ПРОЦЕДУРА. Это должно заставить перекомпилировать. Кстати, я считаю, что заявление DDL обычно автоматически фиксируется, поэтому ничего не должно делать. – Leigh

ответ

0

попробовать:

create or replace procedure ... 

Догадка заключается в том, что вы не фиксируете ошибки в процедуре создания, поэтому считаете, что вы обновляете процедуру с помощью более нового определения, но на самом деле это просто ошибка. Используя «create or replace», вы сообщаете Oracle, чтобы создать, если новый еще обновляет существующую процедуру с помощью нового кода.

Я не знаю этого точно (я не запускаю скрипты), но когда я вижу «создавать процедуру» вместо «создавать или заменять», он поднимает флаг.

Надеюсь, что это поможет!

+0

Это не дает ответа на вопрос. Чтобы критиковать или просить разъяснения у автора, оставьте комментарий ниже их сообщения. - [Из обзора] (/ review/low-quality-posts/15135847) – Robert

+0

@ Robert Если я прав, это должно решить проблему. Я попробую объяснить больше, когда у меня будет больше времени, спасибо – tbone

+0

@tbone Это так, но он не работает каждый раз. Поэтому, хотя, к счастью, моя процедура работает сейчас, я по-прежнему неуклонно преуспеваю в обновлении или замене процедур в Oracle. – MystikDan