置換変数&counter
、&id
および&name
PL/SQLブロックがコンパイルされるときにそれぞれ1回評価されます-not 実行中です。
変数は、PL / SQLブロック内で再評価または再プロモートされることはなく、また再プロモートされることもありません。ブロックはデータベース内で単一のユニットとして実行されます-実行のために送信されると、クライアントから独立し、完了するのを待つだけです(中断しない限り、クライアントも処理します)。 PL / SQLは対話型言語ではないため、クライアントの機能(置換変数など)をSQLまたはPL/SQLの機能と混同しないでください。
楽しみのために、counter
に基づいてスクリプトを生成できます。 これは、IDと名前に対して適切な数のプロンプトを実行し、それらを単純な挿入で使用できる形式に変換します。
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;
これにより、prompter.sql
というファイルが作成されます。 (私はそれを/ tmpに入れました;あなたの環境に適した場所に置いてください!); 「値のペアの数」プロンプトが2と答えると、一時的なスクリプトには次のものが含まれているように見えます。
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'"
その一時的なスクリプトは、@
で実行されます。 、これらすべての個々の値の入力をユーザーに求めます。そして、結合された置換変数から構築されたテーブルコレクションは、挿入によって使用される選択で使用されます。