当编译 PL/SQL 块时,替换变量 &counter、&id 和 &name 分别被计算一次 - 不是,因为它正在执行。
变量不会,也不能在 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'"
然后使用@ 运行该临时脚本,提示用户输入所有这些单独的值。然后在 select 中使用由组合替换变量构建的 table 集合,该 select 由 insert 使用。