os: centos 7.4
db: oracle 11.2.0.4
版本
# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core)
#
# su - oracle
Last login: Tue Jan 21 03:40:05 CST 2020 on pts/0
$ sqlplus / as sysdba;
SQL*Plus: Release 11.2.0.4.0 Production on Mon Feb 3 10:29:09 2020
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
SQL> set lines 300;
SQL> set pages 300;
SQL>
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
SQL>
准备数据
SQL> create table orat0 ( c0 varchar2(100),c1 varchar2(100),c2 varchar2(100));
insert into orat0 ( c0,c1,c2) values ('1','1','1');
insert into orat0 ( c0,c1,c2) values('2','2','2');
insert into orat0 ( c0,c1,c2) values('3','3','3');
insert into orat0 ( c0,c1,c2) values('4','4','4');
set lines 300;
set pages 300;
col c0 format a10;
col c1 format a10;
col c2 format a10;
select * from orat0;
C0 C1 C2
---------- ---------- ----------
1 1 1
2 2 2
3 3 3
4 4 4
SQL> create table orat1 as select * from orat0;
delete from orat1 where c0='3' or c0='4';
set lines 300;
set pages 300;
col c0 format a10;
col c1 format a10;
col c2 format a10;
select * from orat1;
C0 C1 C2
---------- ---------- ----------
1 1 1
2 2 2
update 方式一
SQL> set autocommit off;
SQL> show autocommit;
autocommit OFF
SQL> update orat0 a set a.c2=a.c2||a.c2 where a.c0='4';
SQL> select * from orat0;
C0 C1 C2
---------- ---------- ----------
1 1 1
2 2 2
3 3 3
4 4 4444
SQL> rollback;
update 方式二 subquery
SQL> set autocommit off;
SQL> show autocommit;
autocommit OFF
SQL> update orat0 a set a.c2=(select b.c2||b.c2 from orat1 b where a.c0=b.c0);
SQL> select * from orat0;
C0 C1 C2
---------- ---------- ----------
1 1 11
2 2 22
3 3
4 4
SQL> select a.*,nvl(a.c2,'NULL') from orat0 a;
C0 C1 C2 NVL(A.C2,'NULL')
---------- ---------- ---------- ----------------------------------------------------------------------------------------------------
1 1 11 11
2 2 22 22
3 3 NULL
4 4 NULL
SQL> rollback;
未关联上的行会被更新为 NULL
update 方式三 exists
SQL> set autocommit off;
SQL> show autocommit;
autocommit OFF
SQL> update orat0 a set a.c2=(select b.c2||b.c2 from orat1 b where a.c0=b.c0)
where exists (select b.c2||b.c2 from orat1 b where a.c0=b.c0);
SQL> select * from orat0;
C0 C1 C2
---------- ---------- ----------
1 1 11
2 2 22
3 3 3
4 4 4
SQL> rollback;
使用 exists 限定只更新关联上的行
update 方式四 returning
多行 returning 须用 bulk collect into
SQL> set autocommit off;
SQL> show autocommit;
autocommit OFF
SQL> set serveroutput on;
SQL> show serveroutput;
serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED
SQL> declare
type v_tp_orat0_c0 is table of orat0.c0%type index by pls_integer;
type v_tp_orat0_c1 is table of orat0.c1%type index by pls_integer;
type v_tp_orat0_c2 is table of orat0.c2%type index by pls_integer;
v_orat0_c0 v_tp_orat0_c0;
v_orat0_c1 v_tp_orat0_c1;
v_orat0_c2 v_tp_orat0_c2;
begin
update orat0 a set a.c2=(select b.c2||b.c2 from orat1 b where a.c0=b.c0)
where exists (select b.c2||b.c2 from orat1 b where a.c0=b.c0)
returning c0,c1,c2
bulk collect into v_orat0_c0,v_orat0_c1,v_orat0_c2
;
for i in 1..v_orat0_c0.count
loop
dbms_output.put_line(v_orat0_c0(i)||'-'||v_orat0_c1(i)||'-'||v_orat0_c2(i));
end loop;
end;
/
1-1-11
2-2-22
SQL> select * from orat0;
C0 C1 C2
---------- ---------- ----------
1 1 11
2 2 22
3 3 3
4 4 4
SQL> rollback;
单行数据,使用 plsql 定义变量的方式(define, variable)
SQL> set autocommit off;
SQL> show autocommit;
autocommit OFF
SQL> set serveroutput on;
SQL> show serveroutput;
serveroutput ON SIZE UNLIMITED FORMAT WORD_WRAPPED
SQL> declare
v_orat0_c0 orat0.c0%type;
v_orat0_c1 orat0.c1%type;
v_orat0_c2 orat0.c2%type;
begin
update orat0 a set a.c2=(select b.c2||b.c2 from orat1 b where a.c0=b.c0)
where exists (select b.c2||b.c2 from orat1 b where a.c0=b.c0)
and a.c0='1'
returning c0,c1,c2
into v_orat0_c0,v_orat0_c1,v_orat0_c2
;
dbms_output.put_line(v_orat0_c0||'-'||v_orat0_c1||'-'||v_orat0_c2);
end;
/
1-1-11
SQL> select * from orat0;
C0 C1 C2
---------- ---------- ----------
1 1 11
2 2 2
3 3 3
4 4 4
SQL> rollback;
参考:
https://docs.oracle.com/cd/E11882_01/server.112/e41084/statements_10008.htm#SQLRF01708