хранимая процедура странное поведение - PullRequest
0 голосов
/ 31 января 2020

У меня есть запрос типа

(SELECT ...
FROM T2
WHERE x=1)

Выбор возвращает список tupel, которые вставляются в T1. Так долго, так хорошо.

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

BEGIN
    INSERT INTO T1
    (SELECT ...
    FROM T2
    WHERE x=value)
END;

Процедура вызывается триггером AFTER INSERT на T3.

Запуск выбора на Oracle 12 c вставляет, например, два ряда в T1. Также работает отлично с другими значениями вместо «1».

При вызове процедуры, хотя и вызывается с другими параметрами, всегда вставляется одинаковое количество строк с одинаковыми значениями. Похоже, он выполняется с тем же параметром, что и нет. Время выполнения процедуры примерно в 18 раз выше, чем при непосредственном запросе оператора вставки.

Выше кода может не скомпилироваться, это просто для демонстрации.

Любая идея, почему Выполнение процедуры занимает так много времени, и почему он явно делает что-то. еще

1 Ответ

1 голос
/ 31 января 2020

Чтение того, что вы описали, звучит так, как будто вы неправильно использовали параметр процедуры. Вот пример, который показывает, что я имею в виду.

Давайте создадим таблицу (как у вас есть T1) и процедуру, которая принимает параметр и выполняет вставку в эту таблицу.

SQL> create table test (deptno number, ename varchar2(10));

Table created.

SQL>
SQL> create or replace procedure p_test (deptno in number)
  2  is
  3  begin
  4    insert into test (deptno, ename)
  5    select deptno, ename
  6    from emp
  7    where deptno = deptno;
  8  end;
  9  /

Procedure created.

I Хотелось бы добавить сотрудников, которые работают в отделе 10:

SQL> select deptno, ename
  2  from emp
  3  where deptno = 10;

    DEPTNO ENAME
---------- ----------
        10 CLARK
        10 KING
        10 MILLER

Хорошо; Я ожидаю, что 3 строки будут вставлены. Давайте назовем процедуру, тогда:

SQL> exec p_test (10);

PL/SQL procedure successfully completed.

Результат:

SQL> select * From test;

    DEPTNO ENAME
---------- ----------
        20 SMITH
        30 ALLEN
        30 WARD
        20 JONES
        30 MARTIN
        30 BLAKE
        10 CLARK
        20 SCOTT
        10 KING
        30 TURNER
        20 ADAMS
        30 JAMES
        20 FORD
        10 MILLER

14 rows selected.

SQL>

Wooops! Не совсем то, что я хотел.

Виноват в этом:

7    where deptno = deptno;

, потому что я назвал параметр точно так же, как имя столбца, поэтому Oracle знает , что это условие всегда выполняется (как будто where 1 = 1) и вставляет все строки, которые он находит в таблице EMP, так как другие условия не применяются.

Что делать? Переименуйте параметр и повторите тест:

SQL> create or replace procedure p_test (p_deptno in number)     --> here
  2  is
  3  begin
  4    insert into test (deptno, ename)
  5    select deptno, ename
  6    from emp
  7    where deptno = p_deptno;                                  --> here
  8  end;
  9  /

Procedure created.

SQL> truncate table test;

Table truncated.

SQL> exec p_test (10);

PL/SQL procedure successfully completed.

SQL> select * From test;

    DEPTNO ENAME
---------- ----------
        10 CLARK
        10 KING
        10 MILLER

SQL>

Гораздо лучше, не правда ли?


Если это то, что вы сделали, теперь вы знаете, как это исправить. Если нет, опубликуйте пример, подобный мне, чтобы мы могли видеть, что вы сделали и как Oracle ответил.


Что касается времени разговора процедуры ... ну, кто знает? Слишком мало информации для вычисления. Отследите сеанс и используйте TKPROF, и вы будете точно знать , что происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...