回答

收藏

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

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

使用此代码,我无法多次运行插入查询。它仅询问ID和名称一次(如果counter中的值大于1)。  `0 B3 I2 u/ p( }- W
declare
& M& r/ h! K; s        counter number := 0 ;( G7 o: l3 M. i& a! @
begin 9 w# `8 m6 o0 r, ~- h& R
        counter := &counter ;
% }" G) F3 G0 A* ?        while counter > 0 loop/ m- m: M: e) K' f$ L- _
               insert into customer values ( &id, '&name' ) ;# m1 R% K2 w6 i
               counter := counter - 1 ;
( a; N# l) ]9 t' l" V8 I" ?! ~* J) M       end loop ;( F0 Y- Q1 N2 y/ l' q& q4 v* G
end ;
! A( _  w+ C# b. Q; B4 n3 B让我借助一个示例进行说明:-
3 h# W! q, z! \: G$ K! n4 W5 K假设我将值2放入counter。这样,它应该询问我两次ID和名称,但只询问一次,然后它将我为ID和名称输入的值复制到表中test两次。; _( i6 e0 a/ R( C& x; ]3 }
我怎样才能解决这个问题?如果不能,请提出替代代码,以解决我的问题。& k& k( P% i0 `
               
" _  a7 ]3 z/ t; N8 }/ M" l% W解决方案:
( y/ k) T  X+ z3 p$ u                2 V$ [/ u7 [' _9 }3 O

  k$ l) m* J- O  a6 o1 h3 h" `6 T# `3 _& ?; A3 d3 Z: |
                当PL / SQL块被编译时( 而不是 正在执行中)&counter,替换变量&id和&name分别被评估一次。 __( W/ l3 q* k7 c& ^( d9 `+ P% _' W/ E+ Y
在PL / SQL块中不能也不可以重新评估或提升变量。该块在数据库中作为一个单元执行-- {) t3 Z4 J: w$ w* Z( M3 k% ~
一旦提交执行,它就独立于客户端,客户端仅等待它完成(除非您中断它,客户端也要处理)。PL /4 r) S2 @) a; W- P+ m
SQL不是一种交互式语言,您不应将客户端功能(例如,替换变量)与SQL或PL / SQL功能混淆。4 |" |. h3 [- `

* R4 a. O, q3 b4 e只是为了好玩,您可以生成一个脚本,基于counter该脚本执行适当数量的ID和名称提示,并将其转换为可以由简单插入使用的格式:' U' x6 t# k/ ~% a: W0 x
set serveroutput on
/ G" N( {* r5 l0 ]$ E  ^! Vset feedback off' v/ a# t5 V4 K3 G5 {
set echo off
; X' q) H+ z6 X( x0 W5 @* _set verify off, q- L% ?$ X6 n1 d$ a. I- R- T
set termout off
8 q# X* `1 |9 x8 Y+ j: c" zaccept counter "How many value pairs do you want to insert?"5 [$ c8 [  g" v5 {! K3 Z: N2 I1 C
var ids varchar2(4000);# h1 B/ N) @0 x6 E; E
var names varchar2(4000);% h$ y0 s. g2 q! h4 V
spool /tmp/prompter.sql
, |( _( G6 H6 X9 y, ^$ Qbegin
9 s- n: B+ n6 O  -- prompt for all the value pairs* P  @+ ~: C9 N5 F- U8 O" n
  for i in 1..&counter loop
& {9 u+ w. ^8 @  K. u. t8 t    dbms_output.put_line('accept id' ||i|| ' number  "Enter ID ' ||i|| '"');: \" q3 e! _7 A8 _( ?! I7 V; o
    dbms_output.put_line('accept name' ||i|| '  char "Enter name ' ||i|| '"');. D8 d8 G1 R$ k# v# S
  end loop;& v; z2 z6 N6 W/ U) M( C2 s9 x
  -- concatenate the IDs into one variable
# y- Y, j0 s, y' l' N: E7 ^  dbms_output.put('define ids="');3 m  Q9 S9 U% R+ h
  for i in 1..&counter loop
& D) t/ n- o; j    if i > 1 then5 J- K8 n) `& j2 z( w0 o
      dbms_output.put(',');: ]7 e2 k/ s1 O6 i3 X/ U
    end if;
8 z3 [+ U, }. H, j0 u; d    dbms_output.put('&'||'id'||i);4 k; `. v7 q; [' T' ?* H/ z4 O5 }" N
  end loop;
4 c$ D9 }- B/ }1 r! l  dbms_output.put_line('"');
1 L, Z% k1 J1 D  -- concatenate the names into one variable& z" n, m: o; I- m+ W" X% g3 U
  dbms_output.put('define names="');) n9 J/ t0 O8 [8 c
  for i in 1..&counter loop2 B5 a# V5 \6 d, l3 T
    if i > 1 then
$ g- ^3 g" ~( j, W2 f      dbms_output.put(',');
3 l1 L0 d. N) e2 z" J    end if;
5 G- }& P( h* ~! `. U3 n    -- each name wrapped in single quotes5 f: K2 o0 z  g1 W9 U
    dbms_output.put(q'['&]'||'name'||i||q'[']');
7 ~7 d) [# U# X4 N' I  end loop;
. Z3 j, A7 i' B4 z  dbms_output.put_line('"');  u( d% R' l' n7 X4 h" b
end;. W8 y, X: y" [! d: A
/9 a# S7 j8 F- q  r+ ~
spool off
2 z; R9 z: x: r5 `@/tmp/prompter
) b1 F3 J6 w6 d% K' s8 Vinsert into customer (id, name)
  c. y9 G/ i) u! y! {select i.id, n.name+ k# @% ~+ o- _6 u5 q3 M% g
from (
) W7 ?0 ^: C) ?) X  select rownum as rid, column_value as id 6 o3 e  \1 ?# E1 h
  from table(sys.odcinumberlist(&ids))9 ^# x1 O0 e$ Y* G- e+ g
) i
8 [, K# N4 _1 y. O1 S5 rjoin (" B2 U) s  j( [6 R5 X
  select rownum as rid, column_value as name
5 Z" r9 @( g! T) J" @/ S7 f  from table(sys.odcivarchar2list(&names))
$ z. }! M1 P' p( \- t( l7 P) n
' K- {8 H- n% z: lon n.rid = i.rid;  W( h8 T. ]: L5 T, S
select * from customer;! \3 {& A  X( P6 G% ?
这将创建一个名为prompter.sql(我已将其放在/  I% I$ y3 C! c( K! Q
tmp中;将其放置在适合您的环境的地方!)的文件;提示“值对数量”为2时,临时脚本将包含以下内容:
7 P( H8 P: W& O- n" w: kaccept id1 number  "Enter ID 1"6 N7 P/ }: L& W( [8 w: m" q' U
accept name1  char "Enter name 1"
' b- D/ Y# O& ?/ b) a: oaccept id2 number  "Enter ID 2"# @% W2 _! u: |2 s
accept name2  char "Enter name 2"
$ ]% s( n" j6 A6 @+ y& L( L; _define ids="&id1,&id2"
  B. ~2 ^8 m" U1 D: i( D. [define names="'&name1','&name2'"
0 g5 y/ h  N6 f, l8 q' n: P# g% K然后使用来运行该临时脚本@,提示用户输入所有这些单独的值。然后,将根据组合的替换变量构建的表集合用于一个select中,该插入将使用该选择。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则