Oracle 增删改(INSERT、DELETE、UPDATE)语句
Ø 简介
本文介绍 Oracle 中的增删改语句,即 INSERT、DELETE、UPDATE 语句的使用。是时候展现真正的技术了,快上车:
1. 插入数据(INSERT)
2. 修改数据(UPDATE)
3. 删除数据(DELETE)
4. 回滚(rollback)的使用
5. 注意事项
1. 插入数据(INSERT)
u 语法:
INSERT INTO TABLE_NAME [(column1[, column2, …]] VALUES(value1[, value2, …]);
说明:
1) INSERT 数据时可以指定列名,也可不指定列名。如果不指定列名,必须为每一列都提供数据,并且顺序必须与列名的顺序一致;如果指定列名,提供的数据需要与指定的列名顺序一致;
2) 插入数据时数字类型的列可直接写入,字符或日期类型的列需要加单引号;
3) 插入的数据必须满足约束规则,主键和 NOT NULL 的列必须提供数据。
u 插入数据的方式
1) 首先,可以在 PL/SQL Developer 中使用 FOR UPDATE 语句
1. 首先执行 SELECT 语句
SELECT * FROM Table01 FOR UPDATE;
2. 点击锁表按钮
3. 编辑数据 -> 记入改变 -> 表解锁按钮
4. 最后点击提交
l 说明:低版本的 PL/SQL Developer 操作与以上类似。
2) 使用 INSERT INTO 语句,插入一条数据
INSERT INTO Table01(Id, Name) VALUES(2, '李四'); --指定所有列
COMMIT; --必须执行提交命令
提示:在平常开发中,建议显示指定插入的列名,有助于提高代码的可读性。
INSERT INTO Table01(Id) VALUES(3); --指定部分列,其他未指定的列表必须可以为空(即 NULL)
COMMIT;
INSERT INTO Table01 VALUES(4, '王五'); --不指定任何列,必须按顺序插入所有列
COMMIT;
3) 使用 INSERT INTO SELECT 语句,插入多条数据
INSERT INTO Table02 SELECT * FROM Table01; --将 Table01 中的所有数据插入 Table02 中(注意:可以指定插入的列;Table02 必须存在;可指定 Table01 的查询条件)
COMMIT;
4) 另外,还可以使用 PL/SQL Developer 中使用变量的方式(该方式不怎么实用,不做详细介绍)
INSERT INTO Table01 VALUE(&Id, &Name);
5) 同时插入多条(支持多表插入)
INSERT ALL
INTO Table01 VALUES(10, '张10')
INTO Table01 VALUES(11, '张11')
INTO Table02 VALUES(20, '李20') --同时插入 Table02
SELECT * FROM DUAL;
COMMIT;
注意:INSERT ALL INTO 在效率上,比逐条执行 INSERT INTO 语句要高很多。
n 注意事项:
1. 在插入数值(number)和字符(char)类型时,Oracle 支持数值与字符相互转换,例如:
字符转数值:
INSERT INTO Tab01(id) VALUES('12a'); --ORA-01722:无效数字
INSERT INTO Tab01(id) VALUES('123'); --插入成功,结果为123
INSERT INTO Tab01(id) VALUES('456.56'); --插入成功,结果为457(四舍五入)
数值转字符:
INSERT INTO Tab01(name) VALUES(123); --插入成功,结果为123
INSERT INTO Tab01(name) VALUES(123.56); --插入成功,结果为123.56
提示:虽然 Oracle 支持这种转换,但是并不建议使用该方式去写入数据,不利于理解和阅读。
2. 插入字符类型字段时,超过指定长度直接报错,例如:
CREATE TABLE Tab02(name varchar2(2) NOT NULL);
INSERT INTO Tab02(name) VALUES('abcd'); --插入失败(并不会截断,而是直接报错)
INSERT INTO Tab02(name) VALUES('ab'); --插入成功,结果为ab
3. 插入字符和日期类型时,必须加上单引号,例如:'中国', '22-08-2018'。
4. 插入的字符类型可以为空(NULL)时,也可以指定为空字符串,例如:
CREATE TABLE Tab03(id number(3) NOT NULL, name varchar2(10) NULL);
INSERT INTO Tab03(id, name) VALUES(1, null); --插入成功,结果为NULL
INSERT INTO Tab03(id, name) VALUES(2, ''); --插入成功,结果也为NULL
INSERT INTO Tab03(id, name) VALUES(3, ' '); --插入成功,结果为' '
SELECT * FROM Tab03 WHERE name IS NULL;
SELECT t.*, dump(name) FROM Tab03 t;
由以上两个查询可以看出,在 Oracle 中对于字符类型,''(空字符串)也将以 NULL 对待,即:空字符串就是 NULL, NULL 也是空字符串。
5. 插入 DATE 类型的字段时,需要对日期格式进行转换,例如:
to_date('1985/10/22', 'yyyy/mm/dd')
2. 修改数据(UPDATE)
u 语法:
UPDATE TABLE_NAME SET column1 = value1[, column2 = value2…] [WHERE 条件];
说明:规则与 INSERT 语句类似。
u 修改数据的方式
1) 同样,也可以在 PL/SQL Developer 中使用 FOR UPDATE 语句,进行修改操作
SELECT * FROM Table01 FOR UPDATE;
说明:操作步骤与插入数据类似,只是一个是修改原有的数据,一个是新增数据。
2) 使用 UPDATE 语句更新
UPDATE Table01 SET Name='张山' WHERE Id=1; --更新多个字段,使用“,”逗号分隔
COMMIT;
3) 子查询更新(多列)
UPDATE Table02 SET(Id, Name) = (SELECT Id, Name FROM Table01 WHERE Id=1) WHERE Id=1; --将 Table02 中的 Id, Name 列更新为 Table01 中的 Id, Name,这里没有其他列,就以 Id 列代替了
COMMIT;
4) 将 A 张表的数据更新至 B 表
在 SQL Server 中支持以下语法将 A 表的数据更新到 B 表:
UPDATE Tab04 SET [money]=t5.[money] FROM Tab05 AS t5
WHERE Tab04.id = t5.id; --Tab04 遇到 t5 相同的记录,只会更新 t5 第一个记录的值,并不会报错
在 Oracle 中不支持以上语句,但可以使用 MERGE INTO 子句来完成,看示例:
--创建表
CREATE TABLE Tab04(id number(3), money number(8,2));
CREATE TABLE Tab05(id number(3), money number(8,2));
--插入数据
TRUNCATE TABLE Tab04;
TRUNCATE TABLE Tab05;
INSERT ALL
INTO Tab04 VALUES(1, 100)
INTO Tab04 VALUES(2, 200)
INTO Tab04 VALUES(6, 600)
INTO Tab04 VALUES(6, 610)
INTO Tab04 VALUES(7, 700)
INTO Tab04 VALUES(9, 900)
INTO Tab05 VALUES(1, 1000)
INTO Tab05 VALUES(2, 2000)
--INTO Tab05 VALUES(2, 2100)
INTO Tab05 VALUES(6, 6000)
INTO Tab05 VALUES(8, 8000)
INTO Tab05 VALUES(9, 9000)
SELECT 1 FROM DUAL;
COMMIT;
--更新数据
MERGE INTO Tab04 t4
USING Tab05 t5 ON(t4.id = t5.id)
WHEN MATCHED THEN UPDATE SET t4.money = t5.money WHERE t1.id < 9; --id=9的记录将不会更新
--查询结果
SELECT * FROM Tab04;
注意事项:
1. Tab04 可以被匹配到多条记录,匹配到多条记录将一同更新;
2. Tab04 没有匹配的记录将不会更新,保持原来的值;
3. Tab05 多条记录与 Tab04 中匹配时,将报错:ORA-30926:无法在原表中获得一组稳定的行(与 SQL Server 不一样)
4. Tab05 的记录与 Tab04 未匹配时,不会报错。
当我希望 Tab05 中相同 Id 中金额最大的一条更新到 Tab04 时,可以这样写:
MERGE INTO Tab04 t4
USING (SELECT id, MAX(money) money FROM Tab05 GROUP BY id) t5 ON(t4.id = t5.id)
WHEN MATCHED THEN UPDATE SET t4.money = t5.money WHERE t4.id < 9; --加了一个被处理过的派生表(t5)
提示:先取消 --INTO Tab05 VALUES(2, 2100) 的注释
--再次查询
SELECT * FROM Tab04;
3. 删除数据(DELETE)
u 语法:
DELETE FROM TABLE_NAME or VIEW_NAME [WHERE <condition>];
注意:删除数据前,该记录如果存在外键关联,需要先删除外键表中的关联数据。
u 删除数据的方式
1) 同样,也可以在 PL/SQL Developer 中使用 FOR UPDATE 语句,进行删除操作
SELECT * FROM Table01 FOR UPDATE;
说明:操作步骤与插入数据类似,点击“删除记录”按钮即可。
2) 使用 DELETE 语句
DELETE FROM Table01 WHERE Id=3;
COMMIT;
3) 使用 TRUNCATE 语句
TRUNCATE TABLE Table02;
n 注意事项
TRUNCATE 语句具有以下特征:
1. 不能加 WHERE 条件,清除整表数据;
2. 不需要 COMMIT 提交,不支持事务回滚,并且会结束 SAVEPOINT(回滚点);
3. 效率高于 DELETE 语句(速度较快);
4. 不记录日志,并清除所占用的空间;
5. 不会触发 DELETE 出发器等特点。
而 DELETE 语句的特征:
1. 可以根据条件删除数据;
2. 需要显示 COMMIT 提交,支持事务回滚;
3. 会记录更新日志,删除后仍然占用物理空间;
4. 会触发 DELETE 触发器等。
4. 回滚(rollback)的使用
当我们在编写 SQL 代码进行 CUD 时,可以设置回滚点,将当前操作数据回滚到某一个状态下。创建回滚点使用 SAVEPOINT savepoint_name 语句,回滚到指定位置使用 ROLLBACK TO savepoint_name 语句,示例如下:
--创建表
CREATE TABLE Tab06(id number(3), money number(8,2));
--创建回滚点:SAVE_INSERT
SAVEPOINT SAVE_INSERT;
--插入数据
--TRUNCATE TABLE Tab06;
INSERT ALL
INTO Tab06 VALUES(1, 100)
INTO Tab06 VALUES(2, 200)
SELECT * FROM DUAL;
--创建回滚点:SAVE_UPDATE
SAVEPOINT SAVE_UPDATE;
--更新数据
UPDATE Tab06 SET money = money * 10;
--创建回滚点:SAVE_DELETE
SAVEPOINT SAVE_DELETE;
--删除数据
DELETE FROM Tab06 WHERE id=2;
--可以混滚到任意个回滚点(但只能依次往前回滚):
ROLLBACK TO SAVE_INSERT;
SELECT * FROM Tab06;
ROLLBACK TO SAVE_UPDATE;
SELECT * FROM Tab06;
ROLLBACK TO SAVE_DELETE;
SELECT * FROM Tab06;
n 注意:
当在设置回滚点之后,执行了 TRUNCATE 语句,回滚点将失效;
当在执行过程中,创建了多个回滚点后,如果回滚到前一个回滚点后,就不能再回滚到后一个回滚点了,只能依次往前回滚。
5. 注意事项
1) 在 Oracle 中,所有有关对数据更改的操作(即:INSERT、UPDATE、DELETE)语句,执行完成后,都必须执行提交命令(COMMIT)。
2) 当使用 FRO UPDATE 语句增删改时,并点击锁表按钮后会进行锁表,锁表后其他会话将不能进行增删改操作,所以不建议使用该方式。
Oracle 增删改(INSERT、DELETE、UPDATE)语句的更多相关文章
- [转]Android 如何对sqlite数据库进行增删改[insert、update和delete] 操作
import android.content.ContentValues; import android.content.Context; import android.database.Cursor ...
- 2016/3/26 连接数据库 网页中数据的增删改 add delete update addchuli updateChuLi test8 DBDA
主页面 test8.php <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...
- MySQL增删改查的常用语句汇总
MySQL增删改查的常用语句汇总 以下是总结的mysql的常用语句,欢迎指正和补充~ 一.创建库,删除库,使用库 1.创建数据库:create database 库名; 2.删除数据库:drop da ...
- 带有OUTPUT的INSERT,DELETE,UPDATE
原文地址:http://blog.sina.com.cn/s/blog_71460d950100nld2.html OUTPUT是SQL SERVER2005的新特性.可以从数据修改语句中返回输出.可 ...
- sql server 带有OUTPUT的INSERT,DELETE,UPDATE
原文:sql server 带有OUTPUT的INSERT,DELETE,UPDATE OUTPUT是SQL SERVER2005的新特性.可以从数据修改语句中返回输出.可以看作是"返回结果 ...
- MySQL进阶10--DML数据操纵预言: insert/delete/update --多表连接修改/.多表连接删除/多表连接查询-- truncate 和 delete的区别
/* DML -- 数据操纵预言: insert/delete/update */ #一: 插入语句 /* 语法1: insert into 表名(列名,..,列名....) values(值1,值2 ...
- Use Select To Generate Any Insert/Delete/Update Statement
If you don't have the permission to generate script according to an existing db, but you have the re ...
- sqlserver触发器insert,delete,update
Create Trigger [dbo].[upemployee_kefyu_sale] on [dbo].[employee] for update as if update(FullName) b ...
- %ROWTYPE在INSERT和UPDATE语句里的妙用
PL/SQL里的ROWTYPE类型具有非常大的用处和灵活性,现在发现ROWTYPE在insert和update语句里的妙用,可以节省很多代码,特别是在行copy和更新的时候. 在INSERT语句中: ...
随机推荐
- ansible命令参数介绍
-m:要执行的模块,默认为command -a:模块的参数 -u:ssh连接的用户名,默认用root,ansible.cfg中可以配置 -k:提示输入ssh登录密码.当使用密码验证的时候用 -s:su ...
- Zookeeper学习记录及Java客户端连接示例
1. Zookeeper 1.1 简介 ZooKeeper is a centralized service for maintaining configuration information, na ...
- Springmvc配置定时任务注解开发
1.添加命名空间和xsd约束 xmlns:task="http://www.springframework.org/schema/task" http://www.springfr ...
- Shell(2)—数组
Shell(2)-数组 常用的 Bash Shell 只支持一维数组,不支持多维数组. 一.概念 Shell 并且没有限制数组的大小,理论上可以存放无限量的数据.Shell 数组元素的下标也是从 0 ...
- centos查找文件及文件内容
1.查找文件 find / -name 'filename' 2.查找文件夹(目录) find / -name 'path' -type d 3.查找内容 find . | xargs grep -r ...
- Typescript基础(3)——类
前言 今天继续typescript的学习,开始ts类的学习. 类 类的实现 在ES6中新增了类的概念.我们先看ES6中类的实现. class Person { constructor(name,age ...
- js文件中模块化导入swiper.js文件方法
es6导入: 在js文件顶端 import Swiper from "../../assets/javascripts/swiper.min"; import '../../ass ...
- [20190524]使用use_concat or_expand提示优化.txt
[20190524]使用use_concat or_expand提示优化.txt --//上午看了链接https://connor-mcdonald.com/2019/05/22/being-gene ...
- 更改docker默认网段
#本文档旨在说明创建docker时注意的事项:我们在局域网中使用Docker,最常遇到的一个困惑,就是有时候跨网段结果出现网络不通.原因是因为Docker默认生成的网关和我们的局域网网段有时候是冲突的 ...
- 记录一下自己在MVC项目中如何防CSRF攻击,直接上代码
1.前端的处理: 2.后台 1.)添加过滤器,哪里用放哪里 2.)需要验证的方法上直接添加过滤器即可 大功告成 以下为过滤器代码块 /// <summary>/// ajax中加上Anti ...