Oracle数据库考试题(一)update更改多行计算

原创
小哥 3年前 (2022-10-29) 阅读数 49 #大杂烩

前言:

在采访中,我遇到了这样一个问题:目前有两种形式。A表和B表,A表有字段ID,NAME,B该表也包含字段ID,NAME()字段ID和A表的ID一样的,但田野NAME和A表中的NAME不完全相同),使用B表中的NAME更新A表的NAME。

我立刻想到就这么简单,update阿。但再想一想是不可能的。下面将详细描述更改多行数据的四种方法。

1.传统方法--update:(可能是最慢的方法)

--在SQL Server(这是我的回答,面试官很困惑。长期使用SQL server):
update a set a.NAME=b.NAME from A a,B b where a.ID=b.ID --这种效率将会非常快。

在Oracle它只能写成这样:

update A a set a.NAME=(select b.NAME from B b where a.ID=b.ID)
----或者:使用exists限制它。
update A a set a.NAME=(select b.NAME from B b where a.ID=b.ID) 
where exists(select 1 from B b where  a.ID=b.ID)

使用Oracle中员工表emp做例子:

可以直接在Oracle在数据库中执行,test_emp是emp相同的表结构,复制。
update TEST_EMP a
   set a.sal =
       (select b.sal from emp b where a.empno = b.empno)
 where exists (select 1 from emp b where a.empno = b.empno);

在这种情况下,如果A,B两者各有各的特点10000数据,那么它必须扫描整个表。10000*10000时不我待,就会出现性能问题。所以在oracle有没有其他方法可以改善它?

二、inline view嵌入视图:(关联主键字段,速度更快)

方案:

更新临时创建的视图。要求B表的主键字段必须在where条件,并且是=要关联更新表的编号,否则可能会报告错误:ORA-01779:非键值保存表对应的列不能修改。什么时候B当表主键字段与多个列组合时也可能发生此错误。

update 
(
    select a.sal as asal, b.sal as bsal 
    from emp a, test_emp b 
    where a.empno = b.empno
) 
set asal = bsal;

嵌入式视图和子查询之间的区别:(我一直认为它是相同的,但它似乎仍然是不同的。)
子查询是一个完整的查询语句。子查询首先生成结果集并将结果集应用于条件语句。子查询不同于嵌入式视图。嵌入的视图也可以被视为临时查询结果,但嵌入的视图显示在中。from子句,并与其他数据源(数据表、视图等)形成笛卡尔乘积运算。另一方面,子查询单独操作,不对其他数据源执行笛卡尔乘积操作。

三、merge into更新方法:(当关联的字段不是主键时速度更快)

方案:

在alias2中select在数据中,每个都是。alias1进行ON (join condition)比较、如果匹配、更新操作、不匹配、插入操作。
merge不会返回受影响的行数,最多只能关联两个表,适用于连接条件不是主键的字段。

语法:(详细)merge into我又写了一篇文章来解释:先留空)

merge into table_name  alias1   --须操作的桌子 可以使用别名
using (table|view|sub_query) alias2      --数据来源 可以是表、视图或子查询。
on (join condition)   --关联条件
when matched then              --当关联条件成立时 更新、删除、插入where部分可选 
  --更新
  update  table_name set  col1=colvalue  where……
  --删除  
  delete from table_name  where  col2=colvalue  where……
--只能更新,不能删除 您也可以只删除而不更新。
--如果更新和删除同时存在,则删除条件必须在更新条件内,否则不能删除数据。
when not matched then      --当关联条件不成立时   插入
  insert (col3) values (col3values)  where……; 

--例如:
merge into test_emp  a   --须操作的桌子 可以使用别名
using emp b        --源表
on (a.EMPNO = b.EMPNO)   --目标表和源表之间的相关性。
when matched then              --当关联条件成立时 更新、删除、插入where部分可选 
  update set  a.sal= b.sal where a.empno = 7566 
when not matched then    
  insert (a.empno, a.ename, a.job, a.mgr, a.hiredate, a.sal, a.comm, a.deptno) 
  values (b.empno, b.ename, b.job, b.mgr, b.hiredate, b.sal, b.comm, b.deptno);

4.快速游标更新方法:(逻辑复杂时高效)

方案:

配合oracle独一无二的内置ROWID物理字段,使用快速游标,不需要定义,直接编写游标for循环,快速定位并执行更新。它可以支持复杂的逻辑查询语句,更新准确,无论多少数据,更新效率仍然很高。但是,在执行后不返回受影响的行数。

语法:

begin
for cr in (查询语句) loop  --循环
update table_name set ...   --UPDATE语句(基于查询的结果集)
end loop;  --结束循环
end;

例如:

begin
for emp_cursor in (select a.rowid, b.sal sal from test_emp a, emp b where a.empno = b.empno)
  loop
    update test_emp set sal = emp_cursor.sal
    where rowid = emp_cursor.rowid;
    end loop;
end;

5.四种方法的比较:

方法描述

适用范围

运行效率

传统方案

一般情况也适用。

单表更新高效稳定,多表更新速度较慢。

inline view更新法

关联的字段是主键。

速度较快

merge更新法

关联字段不是主键,适用于两个表的关联。

非主键关联表更新,速度更快

一种快速更新光标的方法

逻辑上复杂的情况

复杂的逻辑是非常有效的。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门