回答

收藏

将UPSERT插入具有动态表名的表中

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

将UPSERT插入表格的任何更好的方法,都提供:6 G4 ~5 d. h8 O6 Y0 Z! }5 V
数据更新速度约为1行/秒
8 I. G+ p8 x# s4 F# ?: p2 O1 u! O表名是DYNAMIC,使用传递给它的ObjectID参数生成
% d' O+ b& ?$ C4 e% F- i3 {

( @# D. h$ [4 v以下过程抛出:“ ORA-00942:表或视图不存在”! e" N  ^/ ]  n
CREATE OR REPLACE PROCEDURE. u. ]/ Y" B( D: I/ n
PROCEDURE "SPINSERTDATA"
! _1 [1 E2 W: b4 C; d" [, p1 s5 _(8 ?2 t* e5 D. Q2 g
  pObjectID IN RAW,
# Y2 C( R2 \6 [6 U) _; z  pDateTime IN TIMESTAMP,
2 }" Y- G9 M1 {6 w  pValue IN BINARY_DOUBLE,& B* j. M4 r3 }: P
)
) e0 W* U$ v5 }- t' Q& IAS
; I; u% M2 o& l( p& MBEGIN
; ~1 D& |0 P7 n/ a' x+ x. F2 c8 S  Declare8 }/ R- n; o1 m2 ]% J
    vQueryInsert VARCHAR2(1000);
" ]) Z5 E! H( I# P( F    vQueryUpdate VARCHAR2(1000);
2 a4 h, L+ O) }+ `9 v    vTableName VARCHAR2(30);8 ]. x# y+ B: P# L' P9 v, t
  Begin      ) v( N  c4 H! H; g; O
      vTableName := FGETTABLENAME(POBJECTID => pObjectID);
! [8 ^. }$ H: V1 q9 D. l" O      vQueryUpdate := 'UPDATE '      || vTableName || ' SET "VALUE" = :1';3 U  ]- n5 ^# Y) i7 l6 ^1 f
      vQueryInsert := 'INSERT INTO ' || vTableName || ' ("DTTIME", "VALUE") VALUES (:1, :2)';
6 o+ }8 S9 u6 Q' w) ~, P      EXECUTE IMMEDIATE vQueryInsert USING pDateTime, pValue;0 x3 L) n6 u9 S! l( `3 }- ~
        EXCEPTION/ Q  G4 E# N  j* }, c
          WHEN DUP_VAL_ON_INDEX THEN 8 g4 j- Y+ J5 p9 z% G! a( w, d9 D0 b
            EXECUTE IMMEDIATE vQueryUpdate USING pValue;; l( b* l8 j2 j3 a1 K) b
  End;
( c: g9 |  u" h: B9 ZEND "SPINSERTDATA";
5 Y& P' h; U: Q) [显然,MERGE不起作用,因为TableName不能是动态的?
  `! y; U6 A* ?我是新手,我编码的第三个月,我在STACKOVERFLOW和Googled中搜寻了3天,尝试各种有趣而绝望的解决方案……即使您发现一个非常相关的链接,也将受到真诚的感谢。
. ^, ^2 ~9 w# U- o

& a/ Z. {: s* p8 T2 m6 c, T                8 U" v  p# f' m9 `! w7 H
解决方案:
7 [" F9 {( g+ i% v0 J                4 c9 @* _6 _9 _$ u
$ k7 r7 l! k3 Y) o) p: B8 L! S

3 f* |, l' k# t# l/ ^                MERGE与本机动态SQL完美配合(立即执行):+ K4 f: q: {; v. J
create table so_test(pk number not null primary key, value varchar2(20));
- H& ^. H& z0 A( @) cinsert into so_test(pk, value) values(1, 'one');
9 Z$ m* F. Y7 _( B1 Adeclare
, ^1 m; w( h8 d3 z  l_SQL varchar2(4000);* ^# [" n7 O( A8 |" m
  l_tablename varchar2(4000) default 'so_test';# \# U/ K7 n8 y0 J; k! q
begin6 D' N3 O- x. O' U& k) m9 Q6 \7 B
  l_SQL := 'merge into ' || l_tablename || ' target' ||! m3 r! z3 `' _" g. F  j
    ' using (select 1 pk, ''eins'' value from dual union all$ w# K# S6 g- a/ E2 v" Z* C5 c
             select 2 pk, ''zwei'' value from dual) source
2 u2 ]9 _2 w2 l+ B. J. v1 N# T% g8 S* `      on (target.pk = source.pk). n: i$ @9 C# f1 r& @6 e! X6 g) |
      when matched then
, G6 F, r: g' l$ ]6 @        update set target.value = source.value
- N7 h. w4 r* e! l/ r' y% }/ X      when not matched then4 K& P% I0 i2 D/ ?4 l% ]4 x4 o7 f
        insert values(source.pk, source.value)      ! D' g- \% q# A
  ';
& G# y0 [- \/ R8 v6 A  dbms_output.put_line(l_sql);; z$ U! r3 a7 I. h) b1 H
  execute immediate l_SQL;& d) L2 I# N3 |
end;6 A3 p* @( B5 h. w2 D
您能否发布使用MERGE时收到的错误消息?
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则