Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como você pode executar a mesma consulta várias vezes usando loop em PL/SQL?


As variáveis ​​de substituição &counter , &id e &name são avaliados uma vez, quando o bloco PL/SQL é compilado - não como está sendo executado.

As variáveis ​​não são e não podem ser reavaliadas ou re-promovidas dentro do bloco PL/SQL. O bloco é executado como uma única unidade dentro do banco de dados - uma vez submetido para execução ele é independente do cliente, que apenas espera sua conclusão (a menos que você o interrompa, o que o cliente também trata). PL/SQL não é uma linguagem interativa e você não deve confundir a funcionalidade do cliente (por exemplo, variáveis ​​de substituição) com a funcionalidade SQL ou PL/SQL.

Só por diversão, você pode gerar um script baseado em counter que faz o número apropriado de prompts para IDs e nomes e os coloca em um formato que pode ser usado por uma simples inserção:
set serveroutput on
set feedback off
set echo off
set verify off
set termout off

accept counter "How many value pairs do you want to insert?"

var ids varchar2(4000);
var names varchar2(4000);

spool /tmp/prompter.sql

begin
  -- prompt for all the value pairs
  for i in 1..&counter loop
    dbms_output.put_line('accept id' ||i|| ' number  "Enter ID ' ||i|| '"');
    dbms_output.put_line('accept name' ||i|| '  char "Enter name ' ||i|| '"');
  end loop;

  -- concatenate the IDs into one variable
  dbms_output.put('define ids="');
  for i in 1..&counter loop
    if i > 1 then
      dbms_output.put(',');
    end if;
    dbms_output.put('&'||'id'||i);
  end loop;
  dbms_output.put_line('"');

  -- concatenate the names into one variable
  dbms_output.put('define names="');
  for i in 1..&counter loop
    if i > 1 then
      dbms_output.put(',');
    end if;
    -- each name wrapped in single quotes
    dbms_output.put(q'['&]'||'name'||i||q'[']');
  end loop;
  dbms_output.put_line('"');
end;
/
spool off

@/tmp/prompter

insert into customer (id, name)
select i.id, n.name
from (
  select rownum as rid, column_value as id 
  from table(sys.odcinumberlist(&ids))
) i
join (
  select rownum as rid, column_value as name
  from table(sys.odcivarchar2list(&names))
) n
on n.rid = i.rid;

select * from customer;

Isso cria um arquivo chamado prompter.sql (Coloquei em /tmp; coloque-o em algum lugar adequado ao seu ambiente!); com o prompt 'number of value pairs' respondido como 2, esse script temporário pareceria conter:
accept id1 number  "Enter ID 1"
accept name1  char "Enter name 1"
accept id2 number  "Enter ID 2"
accept name2  char "Enter name 2"
define ids="&id1,&id2"
define names="'&name1','&name2'"

Esse script temporário é então executado com @ , solicitando ao usuário todos esses valores individuais. E então as coleções de tabelas construídas a partir das variáveis ​​de substituição combinadas são usadas em um select, que é usado pela inserção.