sql >> Database >  >> RDS >> Oracle

Hoe kun je dezelfde query meerdere keren uitvoeren met lus in PL/SQL?

De substitutievariabelen &counter , &id en &name worden elk één keer geëvalueerd, wanneer het PL/SQL-blok wordt gecompileerd - niet terwijl het wordt uitgevoerd.

De variabelen zijn niet, en kunnen niet opnieuw worden geëvalueerd of gepromoveerd binnen het PL/SQL-blok. Het blok wordt uitgevoerd als een enkele eenheid binnen de database - als het eenmaal is ingediend voor uitvoering, is het onafhankelijk van de client, die gewoon wacht tot het is voltooid (tenzij u het onderbreekt, wat de client ook afhandelt). PL/SQL is geen interactieve taal en u moet clientfunctionaliteit (bijv. vervangingsvariabelen) niet verwarren met SQL- of PL/SQL-functionaliteit.

Gewoon voor de lol, je zou een script kunnen genereren op basis van counter die het juiste aantal prompts voor ID's en namen doet en ze in een formaat brengt dat kan worden gebruikt door een eenvoudige invoeging:

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;

Dat creëert een bestand met de naam prompter.sql (Ik heb het in /tmp; zet het ergens geschikt voor uw omgeving!); met de prompt 'aantal waardeparen' beantwoord als 2 dat het tijdelijke script eruit zou zien, bevat:

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'"

Dat tijdelijke script wordt dan uitgevoerd met @ , waarbij de gebruiker om al die individuele waarden wordt gevraagd. En vervolgens worden tabelverzamelingen die zijn opgebouwd uit de gecombineerde vervangingsvariabelen gebruikt in een select, die wordt gebruikt door de insert.




  1. Kunt u een LIKE-query niet gebruiken in een JDBC PreparedStatement?

  2. Aanmeldingsstroom in R12.2 en eenvoudige probleemoplossing

  3. Plsql om nummer (valuta) naar Italiaanse valuta te spellen zonder het vertalingsnummer hardgecodeerd te hebben

  4. Kan geen verbinding maken met server - Een netwerkgerelateerde of instantiespecifieke fout