хранимая процедура вызова оракула в выборе

Я работаю над запросом (ВЫБОР), и я должен вставить результат этого в таблице. Прежде, чем сделать вставку у меня есть некоторая проверка, чтобы сделать, и если все столбцы будут действительны, то я сделаю вставку.

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

Процедура делает проверки и вставляет значения, весь OK.

Я tryied для вызова процедуры в моем ВЫБОРЕ, но это не делает работ.

SELECT field1, field2, myproc(field1, field2)

from MYTABLE.

Этот вид кода не делает работ.

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

Кто-либо, какая-либо идея?

14
задан meagar 12 June 2012 в 12:47
поделиться

3 ответа

использовать цикл PL / SQL:

BEGIN
   FOR c IN (SELECT field1, field2 FROM mytable) LOOP
       my_proc(c.field1, c.field2);
   END LOOP;
END;
29
ответ дан 1 December 2019 в 07:38
поделиться

SQL может использовать только функции в проекции: ему нужно что-то, что возвращает значение. Итак, вам придется написать несколько функций. Это плохие новости. Хорошая новость в том, что вы можете повторно использовать все вложения в свои хранимые процедуры.

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

SQL> create or replace procedure salary_rule
  2      ( p_sal in emp.sal%type
  3        , p_job in emp.job%type)
  4  is
  5      x_sal exception;
  6  begin
  7      if p_sal > 4999 and p_job != 'MANAGER' then
  8          raise x_sal;
  9      end if;
 10  exception
 11      when x_sal then
 12          raise_application_error(-20000, 'Only managers can earn that much!');
 13  end salary_rule;
 14  /

Procedure created.

SQL>

Поскольку это процедура, мы не можем использовать ее в операторе SELECT; нам нужно обернуть его функцией. Эта функция просто вызывает хранимую процедуру. Возвращает входной параметр P_SAL. Другими словами, если зарплата действительная (по правилам), она будет возвращена. В противном случае функция повторно вызовет исключение хранимой процедуры.

SQL> create or replace function validate_salary
  2      ( p_sal in emp.sal%type
  3        , p_job in emp.job%type)
  4      return emp.sal%type
  5  is
  6  begin
  7      salary_rule(p_sal, p_job);
  8      return p_sal;
  9  end validate_salary;
 10  /

Function created.

SQL>

Функция должна возвращать значение, которое мы хотим вставить в нашу таблицу. Он не может вернуть какую-нибудь бессмысленную фразу вроде «зарплата в порядке». Кроме того, если мы хотим проверить два столбца, нам нужна отдельная функция для каждого, даже если между ними существует связь, и мы используем одну и ту же хранимую процедуру для проверки их обоих. Хорошее использование ключевого слова DETERMINISTIC.

Вот тест: сантехники не могут заработать 5000 спондуликов ....

SQL> insert into emp
  2      (empno
  3      , ename
  4      , job
  5      , deptno
  6      , sal )
  7  select
  8      emp_seq.nextval
  9      , 'HALL'
 10      , 'PLUMBER'
 11      , 60
 12      , validate_salary(5000, 'PLUMBER')
 13  from dual
 14  /
    , validate_salary(5000, 'PLUMBER')
      *
ERROR at line 12:
ORA-20000: Only managers can earn that much!
ORA-06512: at "APC.SALARY_RULE", line 12
ORA-06512: at "APC.VALIDATE_SALARY", line 7


SQL>

... но менеджеры могут (потому что они этого заслуживают):

SQL> insert into emp
  2      (empno
  3      , ename
  4      , job
  5      , deptno
  6      , sal )
  7  select
  8      emp_seq.nextval
  9      , 'HALL'
 10      , 'MANAGER'
 11      , 60
 12      , validate_salary(5000, 'MANAGER')
 13  from dual
 14  /

1 row created.

SQL>

Обратите внимание, что выброшенное исключение имеет решающее значение для этой работы. Мы не можем написать какую-то причудливую логику IF SALARY IS VALID THEN INSERT в нашем операторе SQL. Итак, если хранимая процедура не вызывает исключение, а вместо этого возвращает некоторую слабую ошибку, функция упаковки должна будет интерпретировать вывод и выбросить собственное исключение.

6
ответ дан 1 December 2019 в 07:38
поделиться

В операторе SELECT нельзя использовать хранимые процедуры. Для этого вы можете использовать функции.

Насколько я понимаю, вы вызываете insert в своем SP, поэтому примите во внимание, что вы можете использовать INSERT / UPDATE в теле функции. Но если вам нужно выполнить некоторые проверки, вы можете использовать функцию, которая будет выполнять эти проверки и использовать эту функцию в вашем операторе выбора.

0
ответ дан 1 December 2019 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: