赞
踩
目录
本文从SQL语句格式角度,谈一谈SQL更新语句的基本格式及其在Oracle中的实践经验(使用场景、注意事项)。可供数据库管理系统学习者、数据分析员、数据统计员、不太熟悉SQL的程序员等参考。
相对查询语句(查询语句的格式可以看我这篇文章关于SQL的SELECT查询语句的一般格式的描述)来说,更新(增、删、查)语句的形式就简单一些。首先明确一点使用insert、update、delete语句时都设计到事务(这类语句在DBMS中执行后都需要提交),所以这里将这三种语句都归类为更新语句。
简单说,insert语句有两种形态。本文从实践角度来分类,个人认为可以分为单行插入,和基于子查询的插入。
- /*单行插入*/
- insert into 表名 (字段名1,字段名2) values (数据值1,数据值2);
-
- /*基于子查询的插入*/
- insert into 表名 (字段名1,字段名2) values 子查询;
基于以上格式,可以衍生出多种形态的插入语句,这里举个例子:
- /*假设有表DEPT,只有DEPTNO,DNAME,LOC三个字段*/
- /*插入一行数据的语句有*/
- insert into DEPT values('50','市场部','北京');
- insert into DEPT (DEPTNO,DNAME,LOC) values('50','市场部','北京');
- /*强烈建议使用第二种方法(虽然麻烦一点,但是字段名和数据值都映射地很清楚),第一种方法只有在熟悉字段名的情况(主要是顺序)才能使用,且不便于二次维护*/
这里再说一下上面形式的insert语句的使用场景,从经验来说:
1、适合在dbms中插入少量数据时使用。
2、适合在编程语言中结合循环语句使用。
3、适合在sql脚本中使用,比如提前将其他形式(多为Excel文档和txt文档)的数据,逐行转换为insert语句,写到脚本中运行。
再说一下基于子查询的插入语句的例子:
- /*假设有表EMPLOC,只有EMPNO, ENAME, LOC三个字段*/
- /*假设有表EMP,有EMPNO, ENAME, DEPTNO三个字段*/
- /*假设有表DEPT,有LOC, DEPTNO两个字段*/
- /*以下是向EMPLOC中插入一个查询结果的语句,一次可以插入多行,行数取决于查询语句返回行数*/
- INSERT INTO EMPLOC (EMPNO, ENAME, LOC)
- SELECT E.EMPNO, E.ENAME,D.LOC FROM EMP E LEFT JOIN DEPT D ON E.DEPTNO=D.DEPTNO WHERE E.EMPNO>=7499;
说一下以上形式语句的应用场景:
1、适用于在DBMS中对已有表进行加工后进行批量插入。可以用于人工干预的交互式数据迁移工作。
2、个人认为不便于在业务程序中使用,因为查询结果可变性相对较大,不便于对业务数据的把控。如果要遍历查询结果来判断,那么就没有必要写这样的语句,如果是使用PL/SQL(过程化查询语言),那么完全可以用游标+单行插入来替代。
一般来说,update语句只有一种基本格式:
UPDATE 表名 SET 列名1=表达式, 列名2=表达式…… WHERE子句
表名:表或者是视图名。
表达式:可以是函数,也可以是返回单行的子查询。
WHERE子句:和SELECT语句里面的WHERE子句写法一样。
这里举几个例子:
- /*EMPLOC定义同上文*/
- /*单表更新*/
- /*一个典型的更新语句,将EMPNO=7934的员工名字修改为米勒*/
- UPDATE EMPLOC SET ENAME ='米勒' WHERE EMPNO=7934;
-
- /*将EMPNO=7934的员工名字修改为米勒,地区修改为北京*/
- UPDATE EMPLOC SET ENAME ='米勒',LOC='北京' WHERE EMPNO=7934;
-
- /*一个常见但不安全的更新语句,将所有的员工名字修改为米勒,显然不合逻辑。所以UPDATE语句一定要注意WHERE条件,不然就是更新所有行*/
- UPDATE EMPLOC SET ENAME ='米勒';
-
- /*联表更新*/
- /*将EMP的ENAME依据两表EMPNO相等的条件将EMP的ENAME更新至EMPLOC表的ENAME,更新范围限制在EMPLOC为7939内*/
- /*这里是Oracle的写法,其他平台可能不适用*/
- UPDATE EMPLOC EL SET EL.ENAME =(SELECT E.ENAME FROM EMP E WHERE E.EMPNO =EL.EMPNO) WHERE EL.EMPNO=7934;
以上语句:
单表更新,个人认为既适合在程序中使用,也适合在DBMS中使用。
联表更新,个人认为更适用于数据处理员、数据库管理员的工作,比如数据表之间的数据同步、错误数据的处理。
从数据库系统角度(或者简单理解为业务数据管理的角度来说),不到万不得已不要在正式环境使用批量更新、联表更新等操作(风险太高,迫不得已的情况下使用,也须充分熟悉数据库结构,反复测试语句后再使用),而是通过经过成熟稳定的应用程序来做批量更新、“联表更新”等操作。
DELETE语句格式较简单,一般如下:
DELETE FROM 表名 WHERE子句
表名:表或视图。
WHERE子句:和SELECT、UPDATE语句里面的WHERE子句写法一样。
FROM:在Oracle中可以省略。
举例:
- /*删除EMPLOC中EMPNO为7943的行 */
- DELETE FROM EMPLOC WHERE EMPNO=7934;
使用场景:
1、数据库管理员维护数据。
2、业务程序进行业务数据上的删除业务,从程序设计上来说,一定要避免WHERE条件无法生成的bug。从数据库管理角度来说,有类似MySQL安全模式的尽量用安全模式,没有此功能也需要从触发器角度做出一定的限制。
3、个人认为,DELETE语句的功能主要还是行级别的删除。表级别的数据删除用TRUNCATE的效率要高一些。题外话,DROP不是用来清空数据的,是删除整个表,于前两者功能截然不同。除此之外,一些非专业人员的需求,往往会说“把某一列数据的删掉不要”,这种情况其实应该是使用UPDATE语句将对应的字段内容更新为空,并不是DELETE、TRUNCATE、DROP、ALTER TABLE等。初学的朋友需要注意,毕竟数据恢复的成本挺高,专业的DBA也还是稀有人才。
更新语句可以对应SQL中的DML(数据操纵)语言,由于关系数据库的特性,更新语句的使用都伴随着事务和锁 ,这里不展开说事务和锁。主要还是提醒初学的朋友,一定要根据实际情况使用COMMIT(提交)或者ROLLBACK(回滚)来实现最最基础的事务控制,从而避免产生锁表,锁表可能会造成大量的资源耗费,从而导致系统崩溃。
说完了事务控制的提醒,最后就是提醒各位同仁,更新语句一定要慎用。在这个信息时代,数据的价值不比应用程序的价值低,保护好数据是IT人的重要工作之一,所以还是要多注意。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。