回答

收藏

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

技术问答 技术问答 50 人阅读 | 0 人回复 | 2023-09-13

使用此代码,我无法多次运行插入查询。它仅询问ID和名称一次(如果counter中的值大于1)。
6 G( @; C/ h+ o" `" K5 `declare+ m5 H: G5 b7 L
        counter number := 0 ;7 q% u% |. M0 M% x4 {
begin
8 t/ e, L! ]' J        counter := &counter ;
/ |* [( z/ \7 Y* G0 L/ |        while counter > 0 loop
, _" B/ m2 g, a" n7 b               insert into customer values ( &id, '&name' ) ;' q& G- q* J) }& x2 V/ B* T: J3 Q* C
               counter := counter - 1 ;4 e3 d% a" C! w& m* c( E; b+ |
       end loop ;5 N1 ~% \* ]+ j& h% }! O5 S/ V6 x
end ;
$ W. d/ D& c- }7 h6 Q$ o/ O6 ]8 D让我借助一个示例进行说明:-7 K3 G+ u( A  q4 |. s6 S  t" H
假设我将值2放入counter。这样,它应该询问我两次ID和名称,但只询问一次,然后它将我为ID和名称输入的值复制到表中test两次。
; a+ c5 n2 T1 @" Q" ^- \/ J我怎样才能解决这个问题?如果不能,请提出替代代码,以解决我的问题。. U) p, |/ i6 k* s
                8 ?& Q0 |4 x, e
解决方案:
( T6 e; h8 n! w5 v: M) ]               
7 D/ h- M( h) S1 ]: l$ S( J
* [& L# q9 A+ L3 u$ G" L' Y) C2 F& ^2 Y2 m6 A6 ~! ^6 _( O) \
                当PL / SQL块被编译时( 而不是 正在执行中)&counter,替换变量&id和&name分别被评估一次。 __
. |/ t2 l" O2 z7 H& n在PL / SQL块中不能也不可以重新评估或提升变量。该块在数据库中作为一个单元执行-5 E, ^! s) [+ \% L0 s# G' r& Z
一旦提交执行,它就独立于客户端,客户端仅等待它完成(除非您中断它,客户端也要处理)。PL /
; p9 X7 L) {& @# l" b: VSQL不是一种交互式语言,您不应将客户端功能(例如,替换变量)与SQL或PL / SQL功能混淆。
# ^3 C/ ?' v$ \3 m* G% N: J. Q+ N8 l2 a$ R; Q3 F( n
只是为了好玩,您可以生成一个脚本,基于counter该脚本执行适当数量的ID和名称提示,并将其转换为可以由简单插入使用的格式:7 z9 |( u* f/ Z: @
set serveroutput on
- g9 F% R( l$ c' k* ^. Bset feedback off3 J  L7 k9 }% Q7 Q
set echo off
2 b6 p+ o7 e3 Q5 u  [" Sset verify off+ _& v" Q& S3 ?8 B$ V0 F# y
set termout off( [* b! _4 }/ O1 p: a) T
accept counter "How many value pairs do you want to insert?"' v' E) T: x0 j% o& G9 G
var ids varchar2(4000);: m  L$ }6 l% r; x
var names varchar2(4000);
5 J1 U1 t& p; G+ ~7 z4 A+ _spool /tmp/prompter.sql
+ E7 u0 G" b' l. cbegin
- n4 Y& ~, S" _0 F  -- prompt for all the value pairs
* A& p8 Z0 k$ q6 a$ r8 V2 l  for i in 1..&counter loop* x. f' y/ X& F+ P/ H
    dbms_output.put_line('accept id' ||i|| ' number  "Enter ID ' ||i|| '"');
8 e( ~1 a- u4 m+ D" P    dbms_output.put_line('accept name' ||i|| '  char "Enter name ' ||i|| '"');/ _6 h% |% l; l' s5 E
  end loop;
5 L0 I7 u* W: Y2 }. p' C  -- concatenate the IDs into one variable
$ j0 G' K4 @0 I  dbms_output.put('define ids="');
! [! G3 V. V! Y/ l# D  for i in 1..&counter loop
2 u) z- Y* E9 e  G3 M+ u- E5 N' J) G    if i > 1 then
1 N& Y- Y" Z- l' F5 H1 I* c$ H      dbms_output.put(',');
% R3 b4 D- w3 w2 E* N: `( ]    end if;" v) A. Y( O! i* ]% E
    dbms_output.put('&'||'id'||i);
8 d4 s+ d) D' S  end loop;
1 R* I$ Y& H* h; |. y  dbms_output.put_line('"');
+ D8 j/ \2 }3 Q( Y- R  -- concatenate the names into one variable
8 x, W3 Y( j( o, d! c; J7 b  dbms_output.put('define names="');- F2 m! H  h8 Q1 @1 \
  for i in 1..&counter loop1 ?# V! x+ i; }+ ?8 }: e
    if i > 1 then7 |3 z  o' K; E* ]. }9 b% Y
      dbms_output.put(',');
9 ^: R+ d9 R! \: A2 K8 T. E    end if;5 K0 ?$ }9 c+ P% i6 \: i; |0 i
    -- each name wrapped in single quotes0 m, I: o% B) i* }
    dbms_output.put(q'['&]'||'name'||i||q'[']');; l: {( j' n1 N/ J
  end loop;
; G; p; c0 {1 g, F8 b- a  dbms_output.put_line('"');! n5 i" v) T0 h+ w
end;
1 N: N' u; @5 ~9 G8 I/
1 R) W& X, \6 X/ U4 Uspool off
$ W+ s. B1 R; y0 k1 B@/tmp/prompter
2 E0 y3 d+ k9 hinsert into customer (id, name)
1 J- o4 Z# M1 M% ^select i.id, n.name7 ^8 o! n8 B4 r  U# M( l
from (1 j$ i1 r+ |8 z8 V. j  V2 m
  select rownum as rid, column_value as id
, Z* C3 O: N; o! l- p' U  from table(sys.odcinumberlist(&ids))+ }1 n2 k  D+ _( \. h4 W& P+ ]# A
) i
. w( L* a5 b# x8 Z/ s) {" pjoin (
& T; t9 b; P$ _' @; C7 J  select rownum as rid, column_value as name. \; V$ X6 w4 n
  from table(sys.odcivarchar2list(&names))7 D0 f4 c  b+ W$ b
) n& e* L3 B/ H+ c3 ]
on n.rid = i.rid;
$ B: c5 u2 d) j, O/ yselect * from customer;
  o1 |; ?  K7 g' x' Z( T这将创建一个名为prompter.sql(我已将其放在/
. ~; F% r7 r5 Q7 a5 dtmp中;将其放置在适合您的环境的地方!)的文件;提示“值对数量”为2时,临时脚本将包含以下内容:5 X$ i2 X1 d$ v3 V% N
accept id1 number  "Enter ID 1"
, W7 b8 w, G+ j- T' }accept name1  char "Enter name 1"
5 l6 ]! {# P: baccept id2 number  "Enter ID 2"
* z9 h0 o' Z6 @0 x2 M1 q6 maccept name2  char "Enter name 2"
9 L9 ~( E" Q3 v/ W# G% i( W" \define ids="&id1,&id2"
. ]8 n+ T0 x1 e2 ]+ ~/ wdefine names="'&name1','&name2'"6 A* K* p. I" Z( K' e; d' a
然后使用来运行该临时脚本@,提示用户输入所有这些单独的值。然后,将根据组合的替换变量构建的表集合用于一个select中,该插入将使用该选择。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则