Повторение одной и той же переменной связывания несколько раз при использовании структуры OPEN ... FOR dynamici c SQL в Oracle PL / SQL - PullRequest
2 голосов
/ 04 марта 2020

Это продолжение вопроса Винсента Малграта на этот вопрос . Я не могу найти правильный синтаксис для использования, когда вам нужно использовать одну и ту же переменную связывания несколько раз при использовании OPEN...FOR dynamici c SQL. Вы можете увидеть синтаксис для EXECUTE IMMEDIATE здесь (см. «Использование дублирующих заполнителей с Dynami c SQL»)… но не для OPEN...FOR. Различается ли синтаксис с дубликатами-заполнителями при использовании OPEN...FOR? Я использую Oracle 12 c. Это в пакете PL / SQL, а не в анонимном блоке.

Например, этот пример из собственной документации Oracle работает нормально:

DECLARE
   TYPE EmpCurTyp IS REF CURSOR;
   emp_cv   EmpCurTyp;
   emp_rec  emp%ROWTYPE;
   sql_stmt VARCHAR2(200);
   my_job   VARCHAR2(15) := 'CLERK';
BEGIN
   sql_stmt := 'SELECT * FROM emp WHERE job = :j';
   OPEN emp_cv FOR sql_stmt USING my_job;
   LOOP
      FETCH emp_cv INTO emp_rec;
      EXIT WHEN emp_cv%NOTFOUND;
      -- process record
   END LOOP;
   CLOSE emp_cv;
END;
/

Но если вам нужно чтобы ссылаться на переменную связывания :j более одного раза, как вы делаете это в таком случае, когда на :j ссылаются дважды?

sql_stmt := 'SELECT * FROM emp WHERE (job = :j AND name = :n) OR (job = :j AND age = :a)' ;

Я пытался

OPEN emp_cv FOR sql_stmt USING my_job, my_name, my_age;

и

OPEN emp_cv FOR sql_stmt USING my_job, my_name, my_age, my_job;

и в обоих случаях выдает эту ошибку:

ORA-01008: not all variables bound

Ответы [ 2 ]

1 голос
/ 04 марта 2020

Повторные заполнители topi c здесь хорошо описаны https://docs.oracle.com/database/121/LNPLS/dynamic.htm#LNPLS631. Одним словом, в USING параметры предложения обрабатываются по позициям, поэтому вы можете использовать переменную несколько раз в запросе, но для каждого вхождения должно быть указано отдельное значение в USING выражении.

1 голос
/ 04 марта 2020

Вам необходимо включить параметр дважды в предложении USING:

 OPEN emp_cv FOR sql_stmt USING my_job, my_job;

Вот ваш пример, но упрощенный:

DECLARE
   TYPE EmpCurTyp IS REF CURSOR;
   emp_cv   EmpCurTyp;
   emp_rec  varchar2(10);
   sql_stmt VARCHAR2(200);
   my_job   VARCHAR2(15) := 'X';
BEGIN

   OPEN emp_cv FOR 'select * from dual where dummy = :j or dummy = :j' 
    USING my_job, my_job;
   LOOP
      FETCH emp_cv INTO emp_rec;
      EXIT WHEN emp_cv%NOTFOUND;
   END LOOP;
   CLOSE emp_cv;
END;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...