Oracle中多表联合更新处理方法详解
2017-01-25 09:13
453 查看
ORACLE中多表关联更新与SQL Server和MYSQL的语法稍有不同,现将ORACLE中多表关联更新的几种方法处理如下:
一、创建测试表和添加测试数据
CREATE TABLE t_test01(
user_id varchar2(20) primary key,
user_name varchar2(10),
remark varchar2(100) default null
);
INSERT INTO t_test01
SELECT '1001','jiajia','你好啊' FROM dual
UNION ALL
SELECT '1002','maimai','' FROM dual
UNION ALL
SELECT '1003','yangyang','' FROM dual
UNION ALL
SELECT '1004','qianqian','' FROM dual
UNION ALL
SELECT '1005','huahua','' FROM dual;
COMMIT;
SELECT * FROM t_test01
CREATE TABLE t_test02(
user_id varchar2(20),
user_name varchar2(10),
address varchar2(100) default null
)
INSERT INTO t_test02
SELECT '1002','xiaoyue','' FROM dual
UNION ALL
SELECT '1003','chengzi','' FROM dual
UNION ALL
SELECT '1004','lili','' FROM dual;
COMMIT;
SELECT * FROM t_test01;
SELECT * FROM t_test02;
二、更新处理方法
1、采用更新内嵌视图集的处理
UPDATE (
SELECT a.user_name,b.user_name AS user_name01
FROM t_test01 a,t_test02 b
WHERE a.user_id=b.user_id
)
SET user_name=user_name01;
COMMIT;
--但是在执行时报如下错误:
ORA-01779:无法修改与非键值保存表对应的列,如图所示:
错误说明:子查询的结果中,更新数据源(t_test02)的内容不唯一,导致被更新对象(t_test01)中的一行可能对应数据源(t_test02)中的多行。
该解决过程:
--1.去重后创建唯一索引
CREATE UNIQUE INDEX t_test02_idx ON t_test02(user_id);
在创建唯一索引之后,就可以执行更新处理了。
SELECT * FROM t_test01;
--2.强制 Oracle 执行,方法是加上 BYPASS_UJVC 注释
UPDATE (
SELECT a.user_name,b.user_name AS user_name01
FROM t_test01 a,t_test02 b
WHERE a.user_id=b.user_id
)
SET user_name=user_name01;
COMMIT;
2、采用MERGE INTO 实现更新
MERGE INTO t_test01 a
USING t_test02 b
ON (a.user_id=b.user_id)
WHEN MATCHED THEN
UPDATE SET a.user_name=b.user_name;
COMMIT;
3、采用Oracle常规更新
UPDATE t_test01 a
SET a.user_name=(SELECT user_name FROM t_test02 b WHERE a.user_id=b.user_id)
WHERE EXISTS (SELECT 1 FROM t_test02 b WHERE a.user_id=b.user_id);
COMMIT;
二、结果分析和建议
方法1的更新处理速度相对较快些;
方法3的更新处理速度相对较慢,平时使用中一般建议使用第一种,第二种方法。
一、创建测试表和添加测试数据
CREATE TABLE t_test01(
user_id varchar2(20) primary key,
user_name varchar2(10),
remark varchar2(100) default null
);
INSERT INTO t_test01
SELECT '1001','jiajia','你好啊' FROM dual
UNION ALL
SELECT '1002','maimai','' FROM dual
UNION ALL
SELECT '1003','yangyang','' FROM dual
UNION ALL
SELECT '1004','qianqian','' FROM dual
UNION ALL
SELECT '1005','huahua','' FROM dual;
COMMIT;
SELECT * FROM t_test01
CREATE TABLE t_test02(
user_id varchar2(20),
user_name varchar2(10),
address varchar2(100) default null
)
INSERT INTO t_test02
SELECT '1002','xiaoyue','' FROM dual
UNION ALL
SELECT '1003','chengzi','' FROM dual
UNION ALL
SELECT '1004','lili','' FROM dual;
COMMIT;
SELECT * FROM t_test01;
SELECT * FROM t_test02;
二、更新处理方法
1、采用更新内嵌视图集的处理
UPDATE (
SELECT a.user_name,b.user_name AS user_name01
FROM t_test01 a,t_test02 b
WHERE a.user_id=b.user_id
)
SET user_name=user_name01;
COMMIT;
--但是在执行时报如下错误:
ORA-01779:无法修改与非键值保存表对应的列,如图所示:
错误说明:子查询的结果中,更新数据源(t_test02)的内容不唯一,导致被更新对象(t_test01)中的一行可能对应数据源(t_test02)中的多行。
该解决过程:
--1.去重后创建唯一索引
CREATE UNIQUE INDEX t_test02_idx ON t_test02(user_id);
在创建唯一索引之后,就可以执行更新处理了。
SELECT * FROM t_test01;
--2.强制 Oracle 执行,方法是加上 BYPASS_UJVC 注释
UPDATE (
SELECT a.user_name,b.user_name AS user_name01
FROM t_test01 a,t_test02 b
WHERE a.user_id=b.user_id
)
SET user_name=user_name01;
COMMIT;
2、采用MERGE INTO 实现更新
MERGE INTO t_test01 a
USING t_test02 b
ON (a.user_id=b.user_id)
WHEN MATCHED THEN
UPDATE SET a.user_name=b.user_name;
COMMIT;
3、采用Oracle常规更新
UPDATE t_test01 a
SET a.user_name=(SELECT user_name FROM t_test02 b WHERE a.user_id=b.user_id)
WHERE EXISTS (SELECT 1 FROM t_test02 b WHERE a.user_id=b.user_id);
COMMIT;
二、结果分析和建议
方法1的更新处理速度相对较快些;
方法3的更新处理速度相对较慢,平时使用中一般建议使用第一种,第二种方法。
相关文章推荐
- 用ADO.Net实现Oracle大批量数据更新优化处理方法
- ORACLE联机日志文件丢失或损坏的处理方法(转载)
- Oracle联机日志文件丢失或损坏的处理方法
- Oracle 排序中常用的NULL值处理方法
- Oracle 排序中常用的NULL值处理方法
- ORACLE联机日志文件丢失或损坏的处理方法
- ORACLE坏块(ORA-01578)处理方法
- ORACLE联机日志文件丢失或损坏的处理方法
- ORACLE坏块(ORA-01578)处理方法
- ORACLE 回滚段表空间数据文件丢失或损坏处理方法(2)
- 一年没有更新自己的BLOG了,主要是记录一些从sqlserver导数据到oracle的解决方法
- Oracle 监听服务不能启动处理方法
- ORACLE批量更新四种方法比较
- ORACLE联机日志文件丢失或损坏的处理方法
- 解决Oracle处理中文乱码的一种方法
- 几个自己写的简单的字符处理方法(更新中)
- 几个自己写的简单的字符处理方法(更新中)
- 批处理自动更新文件部署WinForm应用程序详解
- Oracle联机日志文件丢失或损坏的处理方法
- sql2005安装sp1后报更新出错的处理方法