SQL Fundamentals: 數據更新及事務處理(INSERT INTO,UPDATE,DELETE,事務,鎖)


SQL Fundamentals || Oracle SQL語言

 在SQL語句中,數據操作語言DML由兩部分組成,查詢(DQL)、更新操作(增加,修改,刪除).

  1. 增加數據(INSERT INTO
  2. 數據的更新操作(UPDATE)
  3. 數據的刪除操作(DELETE)
  4. 事務處理

 

1.增加數據(INSERT INTO

  • 數據增加操作指的是向數據表中添加一條新的記錄,而對於數據的插入通常有兩種形式:

一:插入一條新的數據

INSERT INTO 表名稱 [(列1,列2,列3,…)] VALUES (值1,值2,值3,…) ;

二:插入子查詢的返回結果

INSERT INTO 表名稱 [(列1,列2,列3,…)] 子查詢 ;

  • 所接觸到的數據主要有三種(VARCHAR2NUMBERDATE),所以此時對於這三種數據在增加語法之中的編寫要求如下:

NUMBER類型:

直接編寫,例如:123;

VARCHAR2類型:

使用'聲明,例如:“'MLDN'”

(CLOB類型也按照同樣的方式進行);

DATE類型:

可以按照已有的日期格式編寫字符串,例如:“'22-2月 -81'”,

或者是使TO_DATE()函數將字符串變為DATE型數據

而如果為當前日期時間,則直接使用SYSDATE;

 

增加新數據,范例

 

插入一條新的數據

向myemp數據表之中增加一條新的數據

使用完整語法進行數據增加時需要寫上要增加數據的列的名稱;

INSERT INTO myemp(empno,job,hiredate,ename,mgr,sal,comm,deptno)

        VALUES (8888,'CLERK',SYSDATE,'WENDY',7369,800,100,20);

通過子查詢添加數據

編寫完整格式將所有20部門雇員的信息插入到myemp表之中:

INSERT INTO myemp(empno,ename,job,mgr,hiredate,sal,comm,deptno) SELECT * FROM emp WHERE deptno=20 ;

 

 

2.數據的更新操作(UPDATE)

數據庫的更新操作主要是指的對數據表中的數據進行修改,與數據的增加一樣,在數據修改的時候有兩種形式:

一:由用戶自己指定要更新數據的內容

UPDATE 表名稱 SET 字段= [,字段=,...] [WHERE 更新條件(s)]

二:基於子查詢的更新

UPDATE 表名稱 SET (column,column,...)=(SELECT column,column,... FROM table WHERE 查詢條件(s))

數據更新時可以直接設置更新數據也可以通過子查詢取得更新數據.

 

 

3、更新數據,范例(先寫條件,再寫更新數據)

由用戶自己指定要更新數據的內容

將SMITH(雇員編號為7369)的工資修改為3000元,並且每個月有500元的獎金

UPDATE myemp SET sal=3000,comm=500 WHERE empno=7369;

基於子查詢的更新

將工資低於公司平均薪金的雇員的基本工資上漲20%

UPDATE myemp SET sal=sal*1.2

WHERE sal<(

  SELECT AVG(sal) FROM myemp) ;

一次性上漲公司全部雇員的基本工資,每個雇員的基本工資上漲10%

UPDATE myemp SET sal=sal*1.1 ;

將雇員7369的職位、基本工資、雇佣日期更新為與7839相同的信息

UPDATE myemp

SET (job,sal,hiredate)=(SELECT job,sal,hiredate FROM myemp WHERE empno=7389)

WHERE empno=7369 ;

 

4. 數據的刪除操作(DELETE)

當數據表中的某些數據不再需要時,就可以通過刪除語句進行刪除.

刪除數據時如果沒有指定刪除條件,那么就表示刪除全部數據.

設置的刪除條件可以指定具體的數據也可以設置子查詢.

 

語法:

DELETE FROM 表名稱 [WHERE 刪除條件] ;

更新數據,范例(先寫條件,再寫更新數據)

刪除具體的數據

刪除雇員編號是7566的雇員信息

刪除30部門內的所有雇員

刪除雇員編號為7369、7566、7788的雇員信息

DELETE FROM myemp WHERE empno=7566 ;

DELETE FROM myemp WHERE deptno=30 ;

DELETE FROM myemp WHERE empno IN (7369,7566,7788) ;

刪除子查詢的結果

刪除公司工資最高的雇員

DELETE FROM myemp WHERE sal=(

SELECT MAX(sal) FROM myemp) ;

日期條件

DELETE

FROM myemp

WHERE TO_CHAR(hiredate,'yyyy')=1987;

 

更新行數:

對於更新的三個操作:增加、修改、刪除,每一次都一定會返回當前操作所影響到的數據行數,在java的JDBC操作中更新數據的操作statement和preparedstatement兩個接口,調用的方法是executeUpdate(),返回的是一個int型數據,就是接收更新的行數.

 

5.事務處理

事務處理在數據庫開發中有着非常重要的作用,所謂的事務核心概念就是指一個SESSION所進行的所有更新操作要么一起成功,要么一起失敗,

事務本身具有:原子性(Atomicity)、一致性(Consistency)、隔離性或獨立性(Isolation)、持久性(Durabilily四個特征,以上的四個特征,也被稱為ACID特征

 

Oracle中事務操作命令

命令

描述

SET AUTOCOMMIT=OFF

取消掉自動提交處理,開啟事務處理

SET AUTOCOMMIT=ON

打開自動提交處理,關閉事務處理

COMMIT

提交事務

ROLLBACK TO [回滾點]

回滾操作

SAVEPOINT 事務保存點名稱

設置事務保存點

 

關於SESSION

Oracle 連接(connection)與會話(session)

  • 連接:Communication between a user process and an instance
  • 會話:Specific connection of a user to an instance through a user process

 

 在Oracle數據庫之中,每一個連接到此數據庫的用戶都是一個“SESSION”,每一個SESSION都擁有獨立的事務都可以使事務操作命令,不同的SESSION事務是完全隔離的

服務器依靠SESSION來區分不同的用戶,所以每個會話表示每個用戶。

 

更新緩沖

對於每一個SESSION而言,每一個數據庫的更新操作在事務沒有被提交之前都只是暫時保存在了一段緩沖區之中,並不會真正的向數據庫中發出命令,如果現在用戶發現操作有問題了,則可以進行事務的回滾。

 

回滾存儲點

在默認情況下,執行ROLLBACK命令意味着全部的操作都要回滾,如果現在希望可以回滾到指定操作的話,則可以采用SAVEPOINT設置一些保存點,這樣在回滾的時候,就可以通過ROLLBACK返回指定的保存點上。

 


事務自動提交

設置事務是否自動提交

SET AUTOCOMMIT [ON|OFF]

掌握事務的處理命令

COMMITROLLBACK

 

  范例

打開第一個session

刪除超過32年雇佣的雇員;

原本有14條數據,刪除了11條,還有3條數據

DELETE FROM myemp WHERE MONTHS_BETWEEN(SYSDATE,hiredate)/12>32;

打開第二個session

執行查詢操作,發現在session2中數據仍然有14條數據,

因為更新緩沖,對於每一個SESSION而言,每一個數據庫的更新操作在事務沒有被提交之前都只是暫時保存在了一段緩沖區之中,並不會真正的向數據庫中發出命令,如果現在用戶發現操作有問題了,則可以進行事務的回滾rollback。

回到第一個session

進行事務回滾ROLLBACK;執行完后再查看數據,14條數據又回來了。

如果執行完刪除操作后,現在執行了COMMIT;那么表示正在的發出了更新指令。

回到第二個session

此時session中查詢數據時發現數據已經被更新了。

設置存儲點

INSERT INTO myemp(empno,ename) VALUES(2222,'gaga');

UPDATE myemp SET sal=7000 WHERE empno=2222;

SAVEPOINT sp_a;

INSERT INTO myemp(empno,ename) VALUES(3333,'nacy');

UPDATE myemp SET sal=4000 WHERE empno=3333;

SAVEPOINT sp_b;

 

DELETE FROM myemp WHERE empno in(2222,3333);---------刪除雇員數據

SELECT * FROM myemp;

 

ROLLBACK TO sp_b;

ROLLBACK TO sp_a;

 

 

6.鎖

不同的session同時操作同一資源所發生的問題。

數據只能被一個session操作。

 

鎖表 for update

select for update 是為了在查詢時,避免其他用戶以該表進行插入,修改或刪除等操作,造成表的不一致性.

 

出現鎖的情況

第一個SESSION(scott/tiger連接)執行以下操作

SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;

 

第二個SESSION(scott/tiger連接)執行同樣的操作(這個時候就產生了鎖,只能等待)

SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;

 

鎖的產生


鎖是在多個SESSION訪問同一資源時出現的狀態;

 

鎖的分類

在Oracle中的鎖有以下兩種基本類型:

行級鎖定

記錄鎖定

對當前事務中的一行數據以獨占的方式進行鎖定,在此事務結束之前,其他事務要一直等待該事務完結,例如:之前的范例演示的就是行級鎖定;

表級鎖定

對整張數據表進行數據鎖定,只允許當前事務訪問數據表,其他事務無法訪問。

 

行級鎖定

  • 用戶執行了INSERTUPDATEDELETE以及SELECT FOR UPDATE語句時,Oracle隱式的實現記錄的鎖定,這種鎖定被稱為排它鎖
  • 這種鎖的主要特點是:

當一個事務執行了相應的數據操作之后,如果此時事務沒有提交,那么會一直以獨占的方式鎖定這些操作的數據,其他事務一直到此事務釋放鎖后才可以進行操作。

 

表級鎖定

表級鎖定需要用戶明確的使用“LOCK TABLE”語句手工進行鎖定

LOCK TABLE 表名稱 | 視圖名稱, 表名稱 | 視圖名稱, IN 鎖定模式 MODE [NOWAIT]

NOWAIT這是一個可選項,當視圖鎖定一張數據表時,如果發現已經被其他事務鎖定,不會等待;

鎖定模式有如下幾種常見模式:

ROW SHARE

行共享鎖,在鎖定期間允許其他事務並發對表進行各種操作,但不允許任何事務對同一張表進行獨占操作(禁止排它鎖);

ROW EXCLUSIVE

行排它鎖,允許用戶進行任何操作,與行共享鎖不同的是它不能防止別的事務對同一張表進行手工鎖定或獨占操作;

SHARE

共享鎖,其它事務只允許執行查詢操作,不能執行修改操作;

SHARE ROW EXCLUSIVE

共享排它鎖,允許任何用戶進行查詢操作,但不允許其他用戶使用共享鎖,之前所使用的“SELECT FOR UPDATE”就是共享排它鎖的常見應用;

EXCLUSIVE

排它鎖,事務將以獨占方式鎖定表,其他用戶允許查詢,但是不能修改,也不能設置任何的鎖。

范例:LOCK TABLE myemp IN SHARE MODE NOWAIT ;

 

解除鎖定

盡管用戶清楚了鎖產生的原因,但是在很多時候由於業務量的增加,可能並不會像本章那樣為用戶清楚的羅列出現鎖的種種可能,所以此時就必須通過其它方式查看是否出現了鎖定以及通過命令手工的解除鎖定。

解除鎖定語法:

ALTER SYSTEM KILL SESSION 'SID , SERIAL#'

在此格式之中發現如果要想結束一個SESSION(結束一個SESSION就表示解鎖),則需要兩個標記:

  • SESSION IDSID(每一個用戶的SESSION由管理員分配)
  • 序列號(SERIAL#

而這兩個內容可以利用的數據字典:“v$locked_objectv$session

 

解除鎖定准備

第一個SESSION(scott/tiger連接)執行以下操作

SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;

第二個SESSION(scott/tiger連接)執行同樣的操作

SELECT * FROM myemp WHERE deptno=10 FOR UPDATE ;

 

管理員解鎖(sys/change_on_install

  • 查看數據庫中的鎖定情況v$locked_object

SELECT session_id,oracle_username,process from v$locked_object ;

  • 查詢v$session數據字典

SELECT sid,serial#,username,lockwait,status FROM v$session where sid IN (17,245,477) ;

  • 解除死鎖(注意,這里的'245,2867'分別是sidserial#)

  ALTER SYSTEM KILL SESSION '245,2867';

 

補充一點:查詢當前sessionsid的方法(v$mystat): select distinct sid from v$mystat;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM