использование переменной связывания - PullRequest
7 голосов
/ 06 марта 2011

Можем ли мы использовать переменную связывания в oracle внутри процедуры или функции?

Я пытаюсь обновить переменную связывания внутри моей процедуры.Могу ли я сделать это в любом случае?

if (condition) then
    :v_bind:=10;
end if;

Могу ли я сделать вышеуказанное внутри процедуры или функции ..?


variable v_bind number; 
create procedure abc as v_one 
BEGIN 
  select count(a) into v_one from ab; 
  if(v_one<>0) then 
     :v_bind:=10; 
  end if; 

Смогу ли я это сделать?Это показывает мне плохую переменную v_bind

Ответы [ 3 ]

11 голосов
/ 06 марта 2011

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

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

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

SQL> variable i number
SQL> exec :i := 0;    

PL/SQL procedure successfully completed.

SQL> print :i

         I
----------
         0

SQL> create or replace procedure test_proc
  2  as
  3  begin
  4    :i := 9;
  5  end;
  6  /

Warning: Procedure created with compilation errors.

SQL> show errors procedure test_proc;
Errors for PROCEDURE TEST_PROC:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/3      PLS-00049: bad bind variable 'I'

Однако вы можете передать переменную связывания в качестве параметра OUT для процедуры.Затем процедура может присвоить значение параметру OUT, и это значение затем будет сохранено в вашей переменной bind.

Предположим, у нас есть следующая процедура:

CREATE OR REPLACE PROCEDURE do_stuff (
  p_output    OUT INTEGER
)
AS
BEGIN
  p_output := 6;
END;

Мы можемиспользуйте это, чтобы установить переменную связывания следующим образом:

SQL> variable i number
SQL> exec :i := 0;

PL/SQL procedure successfully completed.

SQL> print :i

         I
----------
         0

SQL> exec do_stuff(:i);

PL/SQL procedure successfully completed.

SQL> print :i

         I
----------
         6
1 голос
/ 09 марта 2011

Нет, вы не можете делать то, что просите.Переменные связывания в plsql обрабатываются прозрачно.Вы не будете явно кодировать переменные связывания, если не собираетесь использовать команду «немедленное выполнение» для запуска кода вне plsql следующим образом:

declare
   v_bind number := 1;
begin
   execute immediate 'select * from table where x = :v_bind';
end;`

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

declare 
  v_bind number := 1
  y number;
begin
  select count(*) into y from table where x = v_bind;
end;
0 голосов
/ 26 апреля 2014

Нельзя связать переменную sqlplus в сеансе с функцией / процедурой.Это выдаст вам ошибку «Bad bind variable».Вы можете просто передать переменную bind из сеанса oracle в любую процедуру.

Давайте рассмотрим пример

    variable v1 NUMBER;

    begin
       select salary into :v1 from employees where employee_id = 100;
       dbms_output.put_line(:v1);
   end;
   /

И если вы запустите приведенный выше пример, заключив его в процедуру / функцию, он покажетВы ошибаетесь.

   create or replace procedure proc is
   begin
      select salary into :v1 from employees where employee_id = 100;
      dbms_output.put_line(:v1);
   end;
   /

Ошибка -

PROCEDURE proc compiled
Warning: execution completed with warning
3/20           PLS-00049: bad bind variable 'V1'
4/22           PLS-00049: bad bind variable 'V1'

Таким образом, невозможно использовать переменные связывания на уровне сеанса в процедурах / функциях.В приведенном ниже примере t2 является переменной связывания

create or replace procedure proc is
    t2 NUMBER;
    begin
       select salary into t2 from employees where employee_id = 100;
       dbms_output.put_line(t2);
    end;
    /

Вы можете вызвать эту процедуру из sqlplus как

exec proc;
...