Проблема с хранимой процедурой в SQL Developer — нет «обновления» изменений, внесенных в блок

#sql #oracle #plsql

#sql #Oracle #plsql

Вопрос:

N.B, проблема, с которой я сталкиваюсь, связана не с бизнес-логикой, а скорее с самой хранимой процедурой. это очень странная проблема, с которой я сталкиваюсь, и у меня раньше не было такой проблемы.


Я изменяю хранимую процедуру, написанную на PL / SQL, называемую « MY_STORED_PROC «, и каждый раз, когда я меняю ее содержимое, предыдущие изменения все еще остаются в результате выполнения SP.

Это пример хранимой процедуры:

 create or replace PROCEDURE MY_STORED_PROC
(
    V_USER IN VARCHAR2 DEFAULT NULL,
    V_NUMBER_PARAM IN NUMBER DEFAULT 0,
    V_ORIGIN IN NUMBER DEFAULT 0
)
AS
    CV_1                    SYS_REFCURSOR; 
    V_SAMPLE                NUMBER;
BEGIN
    SELECT  BAP.APA_CNAME
    INTO    V_USER_DB
    FROM    BH_APPLICATION_PARAM BAP
    WHERE   BAP.APA_NCODE = 84;
        
    INSERT INTO T_DEBUG (ERR_LINE, MESSAGE_INFO)
    SELECT ID, 'EXAMPLE_MESSAGE'
    FROM <my_table> 
    WHERE <ID = 1>;
    
END MY_STORED_PROC;
  

В предыдущей структуре у меня есть EXAMPLE_MESSAGE строка, которая вставляется в T_DEBUG таблицу при выполнении этого SP и выполнении условия.

Теперь, после изменения EXAMPLE_MESSAGE образца строки другим текстом и компиляции и выполнения SP, сообщение EXAMPLE_MESSAGE по-прежнему отображается в результатах.

Я не понимаю, почему — если только этот SP имеет заданный образец строки, а таблица T_DEBUG усекается перед вызовом SP.

Что я пробовал:

  • Выполнить DELETE FROM T_DEBUG; и TRUNCATE TABLE T_DEBUG перед вызовом SP.
  • Выполнить DROP PROCEDURE MY_STORED_PROC , затем выполнить CREATE OR REPLACE PROCEDURE MY_STORED_PROC (с объявлением имени схемы и без него) с полностью измененной логикой процедуры.
  • Скомпилируйте и «Скомпилируйте для отладки» SP — i.e: MY_STORED_PROC с именем схемы и без него.

Пример:

 CREATE OR REPLACE PROCEDURE <SCHEMA>.MY_STORED_PROC ...
CREATE OR REPLACE PROCEDURE MY_STORED_PROC ...
  
  • Измените SP для усечения таблицы T_DEBUG , «которая содержит образец строки» — это действие (до того, как SP выполнит какое-либо действие « i.e. insert data in T_DEBUG «).

  • Удаление хранимой процедуры: DROP PROCEDURE MY_STORED_PROC; и выполнить: CREATE OR REPLACE PROCEDURE <SCHEMA>.MY_STORED_PROC ... .

  • Проверьте T_DEBUG таблицу, и она не содержит никакого триггера — это одна таблица без дополнительных функций или характеристик ( like indexes, triggers, back-up table(s), etc ).

  • Скомпилируйте (SP) со следующим преднамеренным исключением:

      -- Generate intentional DivisionByZero unhandled exception: 
     /*SELECT 1/0 
     INTO V_SAMPLE 
     FROM DUAL;*/
      

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

  • В (30/10/2020) Я также добавил: 'SAMPLE - ' || TO_CHAR(SYSDATE) в качестве примера строки, затем удалил, затем скомпилировал SP — без этого кода — и я все равно получил эту строку образца с датой 30/10/2020 — дата, когда я добавил такой образец, несмотря на то, что я выполнил этот SP в 05/11/2020.

Есть ли какой-либо способ «обновить» хранимую процедуру или какие другие тесты можно выполнить для обновления этой хранимой процедуры?


Я не являюсь администратором базы данных этой базы данных, но я мог бы получить больше информации для обмена с администратором базы данных — я уже объяснил им свою проблему, но помощь не была предоставлена.

Ответ №1:

Хорошо, это звучит странно. «Обновление» не должно требоваться, хранимая процедура хранится в базе данных, и именно она выполняется. Пока вы не используете EBR, нет риска вызова разных версий, если вы выполняете точно такую же процедуру.

Наиболее вероятным объяснением является какая-то глупая ошибка, которую вы упустили из виду, поэтому начните с дальнейшего упрощения вашей процедуры. Вы уже подтвердили сообщением об ошибке, что оно вызывается каждый раз. Удалите другие части вашего кода, чтобы это был просто оператор insert into t_debug, возможно, сделайте так, чтобы он выбирал из dual, а не из другой вашей таблицы с фильтром. Удалите аргументы для процедуры. Попробуйте вставить в другую новую таблицу (возможно, у вас есть триггер). Если вам все же удастся воспроизвести поведение, когда вы упростили его до:

 drop table my_table;
create table my_table (my_string varchar2(200));
create or replace procedure my_proc
is
begin
  insert into my_table (my_string) 
  select 'error 1' from dual;
end;
/
exec my_proc 
select * from my_table;
delete my_table;
create or replace procedure my_proc
is
begin
  insert into my_table (my_string) 
  select 'error 2' from dual;
end;
/
exec my_proc
select * from my_table;
  

Тогда возникает проблема.

Комментарии:

1. Не могли бы вы подробнее рассказать As long as you aren't using EBR , пожалуйста? — Я не понимаю, что вы имеете в виду. Я попробовал, как вы предложили, и проблема продолжается. Я отредактировал свой вопрос, указав, что в этой таблице нет триггеров — это единственная таблица, используемая для временного хранения строк «проверки бизнес-логики» — Странная ситуация, не так ли?

2. EBR — это переопределение на основе редакции. Это позволяет вам иметь несколько программ PL / SQL (и некоторые другие редактируемые объекты) под одним и тем же именем, сеанс будет вызывать ту, которая находится в той же редакции, что и сеанс. По сути, это позволяет выполнять онлайн-обновления с простым переключением на новые версии. Я не думаю, что это здесь уместно, поскольку вы не изменяете свою версию (и, вероятно, у вас даже не включена она).

3. Как только у вас будет упрощенная репликация проблемы от начала до конца, попробуйте ее в другой системе — вы можете использовать livesql.oracle.com для этого. Блок, который я написал, ведет себя точно так, как мы и ожидали. Если у вас этого не происходит, будет полезно поделиться полным случаем здесь.

4. Андрей, извините за поздний ответ. Проблема, к сожалению, MY_STORED_PROC в том, что это звено в цепочке, полная функциональность очень сложна, чтобы поделиться полным случаем здесь, и проблема возникает только в этой среде. Я масштабировал эту проблему с инженером в компании. Честно говоря, я не могу сделать больше, чем это. Я ценю вашу помощь.

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

Ответ №2:

Я думаю, что две наиболее вероятные причины:

  1. вы меняете код в IDE, но забываете его «скомпилировать».
  2. у вас одна и та же процедура в двух разных схемах, и вы не выполняете ту же, которую редактируете.

Ответ №3:

Я, наконец, смог решить эту проблему.

Проблема была связана с данными; в самой базе данных слишком много таблиц, и она сложная, поэтому мне пришлось сгенерировать полный тест программы — после изменения образца текста в хранимой процедуре MY_STORED_PROC на:

 'Testing in LBASPOC - DATE: ' || TO_CHAR(SYSDATE, 'dd/MM/yyyy HH:mi:ss')
  

Результат был следующим:

 Testing in LBASPOC - DATE: 09/11/2020 10:11:30
  

Когда я сгенерировал больше тестов, в таблицу были добавлены новые записи T_DEBUG — и DATE значение менялось в результатах каждого теста:

Примеры:

 Testing in LBASPOC - DATE: 09/11/2020 10:12:29
Testing in LBASPOC - DATE: 09/11/2020 10:21:55
Testing in LBASPOC - DATE: 09/11/2020 10:37:41
  

Затем я обнаружил, что — в других частях программы (т.Е. В базе данных) — были добавлены другие записи (в таблице с именем « T_OBSERV «) — эти записи были основаны на записях из таблицы « T_DEGUB «.

Решение было следующим: измените SP « MY_STORED_PROC » для «перед выполнением каких-либо действий» — удалите дублированные записи в « T_OBSERV «.

Я был уверен, что проблема была в самом SP, но проблема действительно заключалась в дублированных данных.