insert語句
語法:insert into table [(column1, column2...)] values (value1, value2...);
說明:insert語句每次只能向表中插入一條記錄。缺省字段名列表時(shí),應(yīng)為新插入記錄中的每個(gè)字段顯式的設(shè)定新值
也可在insert語句中指定賦值字段列表,只為部分字段顯式設(shè)定新值,其余字段將被缺省賦值為null
舉例:insert into dept values(88,'研發(fā)部','北京');--此句便是缺省字段名列表的情況
insert into dept values(66,'美工部');--這句將執(zhí)行出錯(cuò),提示為沒有足夠的值。即必須為所有字段設(shè)定值
insert into dept(deptno,dname) values(99,'財(cái)務(wù)部');--也可以單獨(dú)為deptno和dname字段賦值
select table_name from user_tables;--用到了數(shù)據(jù)字典表。目的是查詢當(dāng)前用戶方案下所有的表的名字
select user from dual;--查詢當(dāng)前連接到數(shù)據(jù)庫的用戶名
補(bǔ)充:可以在insert語句中使用子查詢,實(shí)現(xiàn)表間數(shù)據(jù)拷貝。在現(xiàn)實(shí)開發(fā)中很少用的到,有點(diǎn)類似Java中的數(shù)組拷貝
比如insert into dept1(id, name) select deptno, dname from dept;
此時(shí)不必再給出values子句。子查詢中的值列表應(yīng)與insert子句中的字段列表相匹配
實(shí)現(xiàn)數(shù)據(jù)復(fù)制的時(shí)候,也可以在應(yīng)用程序?qū)用娌捎眠@種方式進(jìn)行數(shù)據(jù)備份,但一般來說這種備份是不可靠的
應(yīng)該在數(shù)據(jù)庫的層面做備份,也可以由DBA對(duì)整個(gè)數(shù)據(jù)庫做自動(dòng)的數(shù)據(jù)備份處理,包括出現(xiàn)問題的時(shí)候的恢復(fù)
update語句
語法:update table set column1=value1 [, column2=value2, ...] [where condition];
說明:update語句用于更新表中的數(shù)據(jù)。update語句每次可更新多條記錄
可使用where子句限定要更新的記錄,如果缺省where子句,則更新表中的所有記錄
舉例:update emp set sal=sal+88;--將所有員工的工資都漲88元錢
update student2 set phone='010-51288984' where name='張三';--將張三的電話改為010-51288984
delete語句
語法:delete [from] table [where condition];
說明:delete語句用于從表中刪除數(shù)據(jù)。delete語句每次可刪除多條記錄
可使用where子句限定要?jiǎng)h除的記錄,如果缺省where子句,則刪除表中的所有記錄
delete語句并不是刪除整個(gè)表,只是刪除表中的記錄,表仍然存在,還可用來存放數(shù)據(jù)
舉例:delete emp;--等價(jià)于delete from emp;
delete emp where empno=7778;--刪除empno字段的值為7778的所有記錄
merge語句
概述:merge語句用于進(jìn)行數(shù)據(jù)合并,它是根據(jù)條件在表中執(zhí)行數(shù)據(jù)的修改或插入操作
如果要插入的記錄在目標(biāo)表中已經(jīng)存在,則執(zhí)行更新操作,否則執(zhí)行插入操作
實(shí)際開發(fā)的過程中使用它的機(jī)會(huì)并不是很多
語法:merge into table [alias]
using(table|view|sub_query) [alias]
on(join_condition)
when matched then
update set col1=col1_val, col2=col2_val
when not matched then
insert (column_list) values(column_values);
舉例:create table test1(eid number(10), name varchar2(20), birth date, salary number(8,2));
insert into test1 values (1001, 'Stone', '21-1月-10', 8888);
insert into test1 values (1002, 'Smith', '04-1月-09', 6666);
select * from test1;
create table test2(eid number(10), name varchar2(20), birth date, salary number(8,2));
select * from test2;
merge into test2
using test1
on(test1.eid=test2.eid)
when matched then
update set name=test1.name,birth=test1.birth,salary=test1.salary
when not matched then
insert (eid, name, birth) values(test1.eid, test1.name, test1.birth);
select * from test2;
說明:set設(shè)定的是目標(biāo)表中的字段。即將源表中的字段值賦給目標(biāo)表中的字段
insert設(shè)定的也是將字段值插入到目標(biāo)表中。如果要插入全部的字段的值,那么column_list是可以省略的
注意:由于set和insert默認(rèn)都是對(duì)目標(biāo)表進(jìn)行操作,所以,它們后面的字段不可以加目標(biāo)表前綴
即本例中若出現(xiàn)set test2.name=test1.name或insert (test2.eid),執(zhí)行則出錯(cuò),提示信息為標(biāo)識(shí)符無效
事務(wù)控制
概述:也叫做事務(wù)處理。是通過將一組相關(guān)操作組合為一個(gè)要么全部成功,要么全部失敗的邏輯工作單元
以簡化錯(cuò)誤恢復(fù),提高應(yīng)用程序的可靠性。這里指的是在數(shù)據(jù)庫層面所進(jìn)行的一種數(shù)據(jù)庫操作的集成或者說單元化控制
也可以在應(yīng)用程序?qū)用孢M(jìn)行類似的處理。比如說逐個(gè)向數(shù)據(jù)庫發(fā)送多條DML指令,通過先后更新兩個(gè)表以對(duì)應(yīng)轉(zhuǎn)賬操作
如果后面的一個(gè)操作出錯(cuò)了,那么就取消前一個(gè)指令,或者進(jìn)行相反的對(duì)沖的操作
但應(yīng)用程序?qū)用娴倪@種原子的組合,實(shí)際上是不可靠的。在數(shù)據(jù)庫的層面或者在底層來進(jìn)行這種集成,會(huì)更有效有些
事務(wù):組成單個(gè)邏輯工作單元的一系列操作被稱為事務(wù)(Transaction)。實(shí)際上事務(wù)不是僅限于在數(shù)據(jù)庫領(lǐng)域中的一個(gè)概念
數(shù)據(jù)庫事務(wù)通常由0到多條DML語句或1條DDL(Data Define Language)語句或1條DCL(Data Control Language)語句組成
所謂的單個(gè)邏輯工作單元就是能夠完成一個(gè)相對(duì)獨(dú)立的功能,或者說是不應(yīng)該分隔開的一個(gè)操作系列
比如銀行的轉(zhuǎn)賬業(yè)務(wù),該業(yè)務(wù)至少可以分為A賬戶的轉(zhuǎn)出和B賬戶的轉(zhuǎn)入。也就是從A賬戶的余額中減掉一定的數(shù)額
然后再將B賬戶的余額增加一定的數(shù)額。整個(gè)過程等于是修改了兩條記錄,這兩個(gè)操作就可以認(rèn)為就組成了一個(gè)事務(wù)
它們應(yīng)該是一個(gè)單個(gè)的邏輯工作單元,也就是銀行的一個(gè)單筆業(yè)務(wù)
ACID:事務(wù)必須滿足ACID屬性,即原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)
原子性:即事務(wù)中所有操作要么全成功,要么全失敗,它們應(yīng)該作為一個(gè)整體被處理
一致性:事務(wù)執(zhí)行完畢之后,數(shù)據(jù)必須處于一致性的狀態(tài),不能出現(xiàn)數(shù)據(jù)狀態(tài)上的錯(cuò)誤。比如將員工工資級(jí)別從C升到B級(jí)
但工資卻沒有從應(yīng)該的4000升到6000,于是就出現(xiàn)了數(shù)據(jù)的不一致。也就是說這時(shí)的工資級(jí)別雖然是B級(jí)
但工資的數(shù)額卻屬于C級(jí)的范圍。這就說明事務(wù)結(jié)束的時(shí)候,數(shù)據(jù)處于一種不一致性的狀態(tài),會(huì)影響后續(xù)的使用
隔離性:這是相對(duì)其它事務(wù)而言的。有時(shí)可能出現(xiàn)多個(gè)事務(wù)并發(fā)執(zhí)行的情況,比如多個(gè)用戶同時(shí)對(duì)同一個(gè)數(shù)據(jù)庫表進(jìn)行操作
碰巧操縱的又是該表的同一個(gè)數(shù)據(jù)。此時(shí)應(yīng)該有這樣的一個(gè)保證,即當(dāng)前事務(wù)在執(zhí)行過程中所做的數(shù)據(jù)狀態(tài)的改變
是不受其它事務(wù)影響的。其它事務(wù)所讀取或查看的數(shù)據(jù),仍是當(dāng)前事務(wù)執(zhí)行之前的狀態(tài)
直到當(dāng)前事務(wù)結(jié)束,其它事務(wù)看到的才會(huì)是當(dāng)前事務(wù)結(jié)束之后的數(shù)據(jù)狀態(tài)
所有事務(wù)中間的狀態(tài)對(duì)其它事務(wù)而言,是被隔離開的,不受其它事務(wù)影響
持久性:當(dāng)事務(wù)執(zhí)行完畢并提交操作之后,數(shù)據(jù)將永久生效,永久保存在數(shù)據(jù)庫中,將來不可撤銷,不可恢復(fù)
開始:事務(wù)開始于第一條可執(zhí)行語句
結(jié)束:當(dāng)遇到commit或rollback語句、遇到DDL或DCL語句、用戶會(huì)話結(jié)束、系統(tǒng)崩潰等情況時(shí)會(huì)結(jié)束事務(wù)
提交:在執(zhí)行一個(gè)DDL語句、執(zhí)行一個(gè)DCL語句、正常結(jié)束會(huì)話等情況下會(huì)自動(dòng)提交事務(wù)
提交就是讓事務(wù)永久生效,不可撤銷。回滾就是撤銷先前操作,但回滾到事務(wù)開始之前的狀態(tài)時(shí),數(shù)據(jù)仍然是一致的
回滾:當(dāng)會(huì)話異常終止或系統(tǒng)崩潰時(shí),事務(wù)會(huì)被自動(dòng)回滾。事務(wù)的顯式的提交和回滾操作是為了更好的保證數(shù)據(jù)的一致性
狀態(tài):事務(wù)回滾后:數(shù)據(jù)的修改被撤銷。數(shù)據(jù)恢復(fù)到修改前的狀態(tài)。記錄鎖被釋放
事務(wù)提交后:數(shù)據(jù)的修改永久生效,不可撤銷。數(shù)據(jù)以前的狀態(tài)永久性丟失,無法恢復(fù)。保存點(diǎn)(savepoints)被清除
所有用戶(會(huì)話)都將看到操作后的結(jié)果。記錄鎖被釋放,其它用戶此時(shí)才可以對(duì)這些數(shù)據(jù)進(jìn)行修改操作
提交或回滾前:事務(wù)中DML操作結(jié)果只對(duì)當(dāng)前用戶(會(huì)話)可見,其它用戶(會(huì)話)看不到當(dāng)前事務(wù)中數(shù)據(jù)的改變,直到事務(wù)結(jié)束
事務(wù)中DML語句所涉及到的行會(huì)被鎖定,其它用戶(會(huì)話)不能對(duì)其進(jìn)行修改操作,但可以查詢
事務(wù)中數(shù)據(jù)狀態(tài)的改變是可以恢復(fù)的
SqlPlus的自動(dòng)提交
概述:SqlPlus中執(zhí)行SQL語句時(shí)可以設(shè)置是否自動(dòng)提交,缺省為非自動(dòng)提交。這里的提交指的不是事務(wù),而是SqlPlus的每條語句
將來在commit或正常關(guān)閉窗口即關(guān)閉本地到數(shù)據(jù)庫連接的時(shí)候,Sql Plus中的語句也會(huì)被自動(dòng)的提交
設(shè)置:show autocommit;--查看設(shè)置。其中autocommit OFF表示當(dāng)前設(shè)置為非自動(dòng)提交,而autocommit IMMEDIATE代表自動(dòng)提交
set autocommit on;--更改為自動(dòng)提交。set autocommit off;--更改為非自動(dòng)提交
舉例:insert into dept values(88,'Stone','Beijing');
select * from dept;
說明:自動(dòng)提交狀態(tài)為OFF的情況下,這是一個(gè)未提交的事務(wù)。插入新記錄的操作并沒有永久生效,只是當(dāng)前用戶(會(huì)話)可見
其它會(huì)話中看不見這個(gè)未提交事務(wù),即使當(dāng)前用戶再一次連接到數(shù)據(jù)庫,即建立了一個(gè)新的會(huì)話,也查詢不到88號(hào)記錄
比如不關(guān)閉當(dāng)前SQLPlus,然后再打開一個(gè)SQLPlus窗口,并使用當(dāng)前登錄的scott用戶再一次登錄新打開的SQLPlus窗口
然后執(zhí)行查詢,在結(jié)果中根本沒有查詢到前一次會(huì)話中沒有提交的操作指令,即查詢結(jié)果中沒有88號(hào)記錄
這時(shí)可以在原SQLPlus窗口中顯式的提交一下,即執(zhí)行commit指令。提交完成后,插入88號(hào)記錄的操作便永久生效了
然后回到后打開的SQLPlus窗口中執(zhí)行查詢,查詢結(jié)果中很自然的就查到了88號(hào)記錄
也就是說已經(jīng)提交的事務(wù)影響所有其它的事務(wù)和會(huì)話。而對(duì)于未提交的事務(wù),其它用戶(會(huì)話)是看不見的
保存點(diǎn)(Savepoint)
概述:通過保存點(diǎn)在當(dāng)前的事務(wù)中創(chuàng)建標(biāo)記,將來可回退到指定的標(biāo)記(保存點(diǎn))處,實(shí)現(xiàn)事務(wù)的部分回滾
舉例:insert into dept values(55,'Adv','Beijing');
insert into dept values(56,'Sec','Shanghai');
savepoint p1;
insert into dept values(57,'Acc','Dalian');
select * from dept;
rollback to p1;
select * from dept;
說明:前提是當(dāng)前SqlPlus的設(shè)置是非自動(dòng)提交。所以這些都是當(dāng)前會(huì)話中未提交的事務(wù)
代碼執(zhí)行時(shí)p1之后的數(shù)據(jù)狀態(tài)的改變被撤銷,p1之前的操作仍然存在
若執(zhí)行rollback;則回滾到整個(gè)事務(wù)的最初
更多信息請(qǐng)查看IT技術(shù)專欄