oracle select 行数据_update更新多行数据(oracle)

本文总结了Oracle数据库中处理单表和多表更新的常见方法,包括标准更新、视图更新、Merge语句以及快速游标更新。通过案例详细解释了各种方法的适用场景和效率特点,帮助提升数据库操作效率。

转自:http://blog.itpub.net/25322446/viewspace-767505

说明:笔记总结了在工作中遇到过的几种update方法和各种方法适用的范围。

1.单表更新

方案:使用标准update语法即可,执行稳定且效率较高

update table

set (column1,column2,...)=

value1,value2,...

;

2.多表关联更新

举例:更新gkfq_rec表中所有slid与oa2_ftask表fi_inst相同的行,blzt字段值=oa2_ftask表的ft_lstate。

create table gkfq_rec (

slid char(12) parimary key,

blzt varchar2(50),

wjbt varchar2(100) not null,

........

);

create table oa2_ftask (

fi_inst char(12) parimary key,

fi_state int not null,

ft_lstate int not null,

...

);

方法描述

适用范围

运行效率

传统方案

一般情况适用

单表更新效率高且稳定,多表时效率较慢

inline view更新法

关联字段为主键

速度较快

merge更新法

关联字段非主键,适用于两表关联

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

快速游标更新法

逻辑较复杂的情况

复杂逻辑时效率很高

(1)传统方案(速度可能最慢)

update gkfq_rec a

set blzt=

(select b.ft_lstate from oa2_ftask b where a.slid=b.fi_inst)

where exists

(select 1 from oa2_ftask b where a.slid=b.fi_inst)

;

//子查询返回多行值时,通过where exists条件逐行过滤,一一匹配实现set唯一值

(2)inline view更新法(关联主键字段,速度较快)

方案:更新一个临时建立的视图。要求B表的主键字段必须在where条件中,并且是以=号来关联被更新表,否则可能报错:ORA-01779:无法修改与非键值保存表对应的列。当B表主键字段为多列组合时,也有可能出现这一报错。update (select a.blzt as blzt,b.ft_lstate as ft_lstate

from gkfq_rec a,oa2_ftask b where a.slid=b.fi_inst)

set blzt=ft_lstate

;

(3)merge更新法(关联字段非主键时,速度较快)

语法:

MERGE INTO table_name alias 1

USING (table|view|sub_query) alias 2

ON (join condition)

WHEN MATCHED THEN

UPDATE

SET col1=col_val1,

col2=col_val2

WHEN NOT MATCHED THEN

INSERT (column_list) VALUES (column_values);

方案:在alias2中select出来的数据,每一条都跟alias1进行ON (join condition)比较,若匹配,就进行更新操作,不匹配,执行插入操作。merge不会返回影响行数,且最多只能两表关联,适用于连接条件不是主键的字段。

merge into gkfq_rec a

using oa2_ftask b

on (a.slid=b.fi_inst)

when matched then

update set a.blzt=b.ft_lstate;

(4)快速游标更新法(复杂逻辑时,效率很高)

语法:

begin

for cr in (查询语句) loop  --循环

update table_name set ...   --更新语句(根据查询出来的结果集合)

end loop;  --结束循环

end;

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

begin

for aa in (select a.rowid as rowid,b.ft_lstate as ft_lstate from gkfq_rec a,oa2_ftask b

where a.slid=b.fi_inst ) loop

update gkfq_rec set blzt=aa.ft_lstate

where rowid=aa.rowid;

end loop;

end;

mysql update改动多条数据

通常情况下,我们会使用下面SQL语句来更新字段值: 复制代码代码例如以下: UPDATE mytable SET myfield='value' WHERE other_field='other_va ...

MySQL插入,更新,删除数据

插入 单行插入 1.insert into 表名 values(col1_value,col2_value,...); 每个列必须提供一个值,如果没有值,要提供NULL值 每个列必须与它在表中定义的次 ...

oracle使用 merge 更新或插入数据

OracleCC++C#  总结下.使用merge比传统的先判断再选择插入或更新快很多. 1)主要功能 提供有条件地更新和插入数据到数据库表中 如果该行存在,执行一个UPDATE操作,如果是一个新行, ...

在oracle中使用merge into实现更新和插入数据

目录 oracle中使用merge into DUAL表解释 使用场景 用法 单表 多表 oracle中使用merge into DUAL表解释 在Oracle数据库中,dual是Oracle中的一个 ...

在UPDATE中更新TOP条数据以及UPDATE更新中使用ORDER BY

正常查询语句中TOP的运用: SELECT TOP 1000 * FROM MP_MemberGrade   随意更新一张表中满足条件的前N条数据: UPDATE TOP (1) MP_Member ...

Oracle一列的多行数据拼成一行显示字符

Oracle一列的多行数据拼成一行显示字符   oracle 提供了两个函数WMSYS.WM_CONCAT 和 ListAgg函数.    www.2cto.com   先介绍:WMSYS.WM_CO ...

ASP.NET网页动态添加、更新或删除数据行

ASP.NET网页动态添加.更新或删除数据行 看过此篇 http://www.cnblogs.com/insus/p/3247935.html的网友,也 ...

SQL Server下ADO.NET 怎么获取数据库SQL语句INSERT,UPDATE,DELETE了多少行数据

ADO.NET 在发送SQL语句到SQL Server数据库后,怎么知道真正INSERT,UPDATE,DELETE了多少行数据呢? 使用SQL Server内置的全局变量@@ROWCOUNT即可,@ ...

oracle 分组取第一行数据 ,查询sql语句

oracle  分组取第一行数据 SELECT * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY x ORDER BY y DESC) rn, t.* FR ...

随机推荐

获取URL最后一个 ‘/’ 之后的字符

在开发项目的过程中,经常遇到需要解析论坛,博客等的URL的问题,比如:'abc/def/jkl' 或 'abc/def/jkl/',获取最后一个‘/’之后的所有字符‘jkl’,由于特殊字符'/'的个数 ...

js--敏感词屏蔽

EXCEL导入(反射)

import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...

Nagios 自定义插件与安装使用之监控dead datanodes

现在我使用nagios来监控hadoop的核心进程,rm,nm,dn,nn,zkfc,jn,zk等,但是有时候进程虽然还在,但是日志不刷新,web ui上可以看到有些datanodes节点已经变为de ...

VC++ AfxBeginThread 与 CreateThread 的区别

简言之:AfxBeginThread是MFC的全局函数,是对CreateThread的封装.    CreateThread是Win32 API函数,前者最终要调到后者.具体说来,CreateThre ...

dict和set

#dict和set #dict #Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map #使用键-值(key-value)存储,具有极快的查找速度. #字 ...

HTML5客户端数据存储

HTML5 使在不影响网站性能的情况下存储大量数据成为可能.之前,这些都是由 cookie 完成的,cookie不适合大量数据的存储,因为会影响速度. 举个例子: var obj = {x:1}; / ...

Microsoft Visual Studio 2017 编译最新版 libuv 1.x 并且生成 LIB 和 DLL 两种模式

以为昨天晚上编译通过就可以了,哪知道,早上编译DLL的一车的报错 今天开始逐个解决,终于把引用的问题一亿解决了,具体步骤如下 1 在 Windows 平台下编译出错,显示导出未定义,打开 uv-win ...

h5仿微信聊天(高仿版)、微信聊天表情|对话框|编辑器

之前做过一版h5微信聊天移动端,这段时间闲来无事就整理了下之前项目,又重新在原先的那版基础上升级了下,如是就有了现在的h5仿微信聊天高仿版,新增了微聊.通讯录.探索.我四个模块 左右触摸滑屏切换,聊天 ...

<think> 我们可以在Oracle中使用触发器(Trigger)来实现每次插入数据时自动更新update_time字段。假设表中有一个字段叫做update_time,我们希望在插入新记录时,将该字段设置为当前系统时间(例如SYSDATE)。同时,我们可能还希望这个字段在数据更新时也自动更新(根据需求,如果只需要插入时更新,则只在插入时操作)。 以下是一个示例触发器,它在插入(INSERT)操作时自动设置update_time为当前时间: ```sql CREATE OR REPLACE TRIGGER trg_update_time BEFORE INSERT ON 表名 FOR EACH ROW BEGIN :NEW.update_time := SYSDATE; END; / ``` ### 关键说明: 1. **触发器类型**:`BEFORE INSERT`表示在插入操作之前触发。 2. `:NEW.update_time`:代表新插入行的update_time字段。 3. `SYSDATE`:Oracle内置函数,返回当前日期和时间。 ### 扩展:同时支持插入和更新更新 如果需求是不仅在插入时更新,在更新记录时也要更新update_time,可以修改触发器: ```sql CREATE OR REPLACE TRIGGER trg_update_time BEFORE INSERT OR UPDATE ON 表名 FOR EACH ROW BEGIN :NEW.update_time := SYSDATE; END; / ``` ### 注意事项: - **表名替换**:将上述代码中的`表名`替换为实际表名。 - **权限**:创建触发器需要相应的权限。 - **字段存在**:确保表中存在`update_time`字段(类型建议为DATE或TIMESTAMP)。 - **避免递归**:确保触发器内部不会导致递归更新(例如,在更新其他字段时,触发器更新update_time,这个更新不会再次触发该触发器,因为触发器定义在表上,并且更新update_time的操作是在同一次更新语句中完成的,不会再次触发同一种触发器)。 ### 示例表结构: ```sql CREATE TABLE example_table ( id NUMBER PRIMARY KEY, data VARCHAR2(100), update_time DATE -- 或者使用TIMESTAMP类型 ); ``` ### 测试: 插入一条记录,update_time会自动设置: ```sql INSERT INTO example_table (id, data) VALUES (1, '测试数据'); SELECT * FROM example_table; -- 查看update_time是否为当前时间 ``` §§相关问题§§ 1. 如何修改触发器以在插入和更新更新不同的字段(如创建时间和更新时间分开)? 2. 如果希望update_time字段使用UTC时间而非数据库服务器本地时间,应如何调整? 3. 在Oracle中,如何批量禁用和启用某个表上的所有触发器? 4. 当表中已有数据时,如何为现有记录批量初始化update_time字段? 5. 如果需要在多个表上实现相同的更新逻辑,如何避免为每个表重复编写触发器? </think>### Oracle 实现插入数据时自动更新 update_time 字段 在 Oracle 中,可通过以下两种方法实现插入数据时自动更新 update_time 字段: #### 方法 1:使用 DEFAULT 值(推荐) ```sql -- 创建表示例 CREATE TABLE your_table ( id NUMBER PRIMARY KEY, data_content VARCHAR2(100), update_time TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL ); -- 插入数据(自动填充 update_time) INSERT INTO your_table (id, data_content) VALUES (1, '示例数据'); -- update_time 自动设置为当前时间 ``` #### 方法 2:使用 BEFORE INSERT 触发器 ```sql -- 创建表(不设默认值) CREATE TABLE your_table ( id NUMBER PRIMARY KEY, data_content VARCHAR2(100), update_time TIMESTAMP ); -- 创建触发器 CREATE OR REPLACE TRIGGER trg_update_time BEFORE INSERT ON your_table FOR EACH ROW BEGIN :NEW.update_time := SYSTIMESTAMP; END; / -- 插入数据 INSERT INTO your_table (id, data_content) VALUES (2, '触发器示例'); -- update_time 由触发器填充 ``` ### 关键细节说明: 1. **时间精度选择**: - `SYSDATE`:精确到秒(DATE 类型) - `SYSTIMESTAMP`:精确到纳秒(TIMESTAMP 类型),推荐使用 2. **字段约束建议**: ```sql update_time TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL ``` - `NOT NULL` 确保时间不为空 - `DEFAULT` 提供默认值 3. **更新时间同步更新**: 如需在数据修改时也更新该字段,添加更新触发器: ```sql CREATE OR REPLACE TRIGGER trg_update_time_all BEFORE INSERT OR UPDATE ON your_table FOR EACH ROW BEGIN :NEW.update_time := SYSTIMESTAMP; END; ``` ### 性能注意事项: 1. 优先使用 `DEFAULT` 方案(性能优于触发器) 2. 对于分区表,确保 update_time 字段不参与分区键 3. 大表插入时,避免在触发器中添加复杂逻辑
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值