小编典典

如何使用PL / SQL中的循环多次运行同一查询?

sql

使用此代码,我无法多次运行插入查询。它仅询问ID和名称一次(如果counter中的值大于1)。

declare
        counter number := 0 ;
begin 
        counter := &counter ;
        while counter > 0 loop
               insert into customer values ( &id, '&name' ) ;
               counter := counter - 1 ;
       end loop ;
end ;

让我借助一个示例进行说明:-

假设我将值2放入counter。这样,它应该询问我两次ID和名称,但只询问一次,然后它将我为ID和名称输入的值复制到表中test两次。

我怎样才能解决这个问题?如果不能,请提出替代代码,以解决我的问题。


阅读 242

收藏
2021-05-05

共1个答案

小编典典

当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中,该插入将使用该选择。

2021-05-05