Некоторые изменения в хранимых процедурах, похоже, не ... 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
На самом деле я просто понял, что, основываясь на поведении, которое я описал, я бы предположил, что ни одно из изменений, которые я сделал, не было признано Oracle вообще, поэтому оно все еще обновляется на основе существующего v_Month_Year значение, как показано в исходном proc. WTF. – MystikDan
'INT' - это просто подтип' NUMBER'. [oracle doc] (https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/datatypes.htm) –
* скопируйте определение процедуры, переименуйте его и скопируйте *. Чтобы добавить параметр, используйте ALTER ПРОЦЕДУРА. Это должно заставить перекомпилировать. Кстати, я считаю, что заявление DDL обычно автоматически фиксируется, поэтому ничего не должно делать. – Leigh