数据的维护(DML与Transactions)

数据的维护
数据的维护包括了数据库操作语言DML(Data Manipulating Language)和事务控制(Transaction Control)两大部分。其实DML只包含了以下3个语句:
INSERT/UPDATE/DELETE

准备工作:
CREATE TABLE emp_DML(
id VARCHAR2(6),
ename VARCHAR2(20),
dept_id VARCHAR2(6),
salary NUMBER(5,2)
);
CREATE TABLE dept_DML(
id VARCHAR2(6),
dname VARCHAR2(20),
loc VARCHAR2(50)
);
ALTER TABLE emp_DML MODIFY (id CHAR(6),dept_id CHAR(6));
ALTER TABLE dept_DML MODIFY (id CHAR(6));
CREATE SEQUENCE emp_sequence;
CREATE SEQUENCE dept_sequence;
select emp_sequence.NEXTVAL,dept_sequence.nextval FROM DUAL;
INSERT 语句
在往一个表中添加一行新的数据时,需要使用DML语言中的INSERT语句。该语句的格式如下:
INSERT INTO 表名 [(列名[,列名...])]
VALUES (数值[,数值...]);
其中:
表名:要输入数据的表的名字
列名:表中要输入数据列的名字
数值:对应列的具体值
使用以上的INSERT语句格式每一次只能向表中插入一行数据。
例子:
INSERT INTO dept_dml (id,dname,loc)
VALUES (lpad(dept_sequence.NEXTVAL,6,'0'),'美容','煤球胡同');
注意在使用前面的DML语句插入一行数据时,日期型和字符型的数据必须用单引号括起来。您可以在INSERT INTO子句中列出每一个要插入值的列的名字。其数值的数据类型一定与对应的列的数据类型相匹配。您也可以按表中列的默认顺序在VALUES子句中直接列出每一个要插入的数据值,而不用INSERT INTO子句中列出每一个要插入值的列的名字。
例子:
INSERT INTO dept_dml
VALUES (lpad(dept_sequence.NEXTVAL,6,'0'),'订货','狼山市');
开发软件时应列出所有要插入数据的列名,这样会使软件的易读性大为增加,也使软件更容易维护
INSERT语句中的空值(NULL)问题
我们都知道查询语句中的空值(NULL)一直是一个比较头疼的问题
INSERT语句如何插入NULL值
1、在VALUES子句中使用空串('')向dept_dml表中输入一条含有空值(NULL)
INSERT INTO dept_DML (id,dname,loc)
VALUES (lpad(dept_sequence.NEXTVAL,6,'0'),'','牛街');
2、也可以在VALUES子句中使用NULL关键字
INSERT INTO dept_DML (id,dname,loc)
VALUES (lpad(dept_sequence.NEXTVAL,6,'0'),NULL,'安静大街');
3、或者不列出插入的列
INSERT INTO dept_DML (id,loc)
VALUES (lpad(dept_sequence.NEXTVAL,6,'0'),'公关');
利用子查询向表中插入数据
INSERT INTO dept_DML (id,dname,loc)
ELECT SUBSTR(USER_ID,6),NAME_CN,MOB_BELONG_TO
FROM USER_BASE_INFO WHERE NAME_CN IS NOT NULL;
注意:
在使用子查询向某个表中插入数据时不能使用VALUES关键字
INSERT子句中的列数和数据类型必须和子查询中的列名和数据类型一致
使用替代变量向表中插入数据
INSERT INTO emp_dml (id,ename,salary,create_time)
VALUES (lpad(emp_sequence.NEXTVAL,6,'0'),&ename,&salary,TO_DATE(&create_time,'YYYY-MM-DD'));
当然可以使用 ACCEPT为替代变量加提示。

UPDATE 语句
UPDATE emp_dml
SET salary = salary*0.9;
UPDATE语句的格式如下:
UPDATE 表名
SET 列名=值[,列名=值,...]
[WHERE 条件]
其中:
表名:要修改数据的表的名字
列名:表中要修改数据列的名字
数值:对应列的具体值
条件:由列名、表达式、常量、子查询和比较运算符组成,用来决定要修改的数据行
与INSERT语句不同,UPDATE语句可以一次修改多行记录。因此如果您要修个一条记录的话,在写UPDATE语句时就要保证一定只有一条记录满足WHERE子句的条件。
UPDATE语句修改指定数据的时候要注意WHERE条件应该能唯一标识您想要的列。最稳妥的方法时使用主键
基于另一个表来修改记录
UPDATE emp_dml
SET sal = (SELECT losal
FROM salgrade
WHERE grade = 1)
WHERE sal< (SELECT losal
FROM salgrade
WHERE grade = 1)
可以在UPDATE语句中利用基于另一个表的子查询来修改表中的记录。
UPDATE emp_dml
SET (job, sal) = (SELECT job,sal
FROM emp_dml
WHERE empno = 7369)
WHERE job='保安';
可以使用UPDATE语句来同时修改表中的多列,但是在使用这种方法时,在SELECT子句中等号右边的必须是子查询语句
DELETE语句
DELETE FROM emp_dml
WHERE (job = 'MANAGER' AND sal > 2500)
OR (job = 'SALESMAN' AND sal > 1300);
DELETE语句用来删除一个表中存在的行,该语句的格式如下:
DELETE [FROM] 表名
[WHERE 条件];
其中:
表名:要从中删除数据的表名;
条件:由列名、表达式、常量、子查询和比较运算符组成,用来决定要修改的数据行
尽管从SQL语句的易读性来讲应该使用FROM关键字,但许多有经验的Oracle专业人士都不喜欢这一关键字。这可能是为了减少输入量
在DELETE时可能出现的问题
与UPDATE相似,DELETE语句可以删除多条记录。
DELETE删除记录很可怕,使用的时候反复检查WHERE子句中的条件是否正确
基于另一个表来删除记录
DELETE FROM emp_dml
WHERE deptno =
(SELECT deptno
FROM dept_dml
WHERE dname = UPPER('美容'));
如果您比较细心的话,可能早已发现一些您修改过和删除的记录依然在数据库中保持不变。这是因为Oracle的Transaction事务处理机制在发挥作用。

事务
引入事务(Transactions)处理的原因:
简单来说就是并发和一体操作。例子银行取款。
什么是Oracle数据库的事务(Transactions)
为了有效的空值事务(Transactions),Oracle引入了两个显式的事务控制语句,一个是COMMIT,另一个是ROLLBACK。
Oracle数据库的事务可由:
一个或多个DML语句组成
一个DDL语句组成
一个DCL语句组成
那么如何标识一个事务呢?因为Oracle公司在开始时是瞄准联机事务处理(OLTP)的,所以它对事务处理提供了强有力的支持。Oracle可以自动地标识一个事务(Transactions)。
Oracle的一个事务是以第一个可执行的SQL语句开始,当下列事件之一发生时结束。
用户执行了COMMIT语句
用户执行了ROLLBACK语句
用户执行了DDL语句(自动提交)数据库定义语言,比如建表
用户执行了DCL语句(自动提交)事务控制语言COMMIT 等
用户正常退出SQL*PLUS(自动提交)
用户费正常退出SQL*PLUS(自动回滚)
系统崩溃,包括硬件或软件故障(自动回滚)
利用COMMIT和RollBack语句进行事务控制
SQL>UPDATE emp_dml
SET deptno = 88
WHERE deptno = 66;
SQL>SELECT empno, ename, deptno
FROM emp_dml
WHERE deptno > 30;
语句执行完感觉修改成功,让另一个用户登录数据库查询,发现没有改变
SQL> COMMIT;执行完发现可以找到了。
利用DDL和DCL语句进行事务控制
SQL>UPDATE emp_dml
SET sal = 800
WHERE deptno = 88;
SQL>SELECT ename, job, sal
FROM scott.emp_dml
WHERE deptno = 8;
叫同事再次查询发现事务没有提交。您正好需要创建一个名为dept_ddl的临时表(在SCOTT用户中),因此没有必要使用COMMIT命令来提交您做的修改。
SQL>CREATE TABLE dept_ddl
AS
SELECT *
FROM dept;
再叫同事查,发现事务已经提交了。
用DCL结束事务和DDL类似
利用AUTOCOMMIT 进行事务控制
像其他的数据库管理系统一样,您也可以让Oracle数据库管理系统每执行一条DML语句就提交一次事务。
SQL>SET AUTOCOMMIT ON
SQL>UPDATE emp_dml
SET job = 'MANAGER'
WHERE empno = 1002;
查询发现数据已经写入
Oracle数据库管理系统的默认设置AUTOCOMMIT是OFF
有关事务处理应注意的一些问题
学过数据库原理或类似的数,可能记得它们告诉读者:在有人对数据库中的数据进行写入(即DML操作)时,数据库系统为了维护数据的一致性是不允许其他人对该数据进行任何的操作。数据库系统在进行写操作之前,先把要操作的数据行(记录)用排它锁(exclusive lock)锁上。质押记录上有排他锁,数据库系统就不允许其他的人对数据进行任何的操作
尽管在学术上或者理论中完美,实际这样的设计困难,因为很少我们希望一群用户等待一个用户执行结束而无法操作。Oracle允许有人在数据库进行写操作时其他人对该数据进行读操作。每一个Oracle数据库中都有一个或多个回滚的磁盘区。当有人对数据库中的数据进行任何写操作时,Oracle数据库系统首先将原始的数据复制到回滚段中,之后才做响应的操作,在事务处理结束之前其他的用户可以读浙西额数据,但读的是回滚段上的数据

posted @ 2017-01-10 14:34  guodaxia  阅读(269)  评论(0)    收藏  举报