MySQL中DML語句和事務的概念

ML語句

知識要點
DML語句
插入行到表中
刪除表中的行
更新表中的行
控制事務

DML語句
DML:DATA MANIPULATION LANGUAGE(數據操縱語言),由INSERT、UPDATE、DELETE等語句構成,用來修改表中的數據

INSERT語句
1.帶VALUES子句的INSERT語句
INSERT [INTO] tbl_name[(col_name,…)]
{VALUES | VALUE} (expr ,…),(…),…
用來把一個新行插入到表中
爲和其它數據庫保持一致,不要省略INTO關鍵字以及使用VALUES而不是value關鍵字
插入一行時,要求必須對該行所有的列賦值。但是賦值方式可以是顯式賦值(直接給出值)和隱式賦值(由MySQL自動賦值)

2.在表名後面列出所有的列名
示例: 插入一個新的球隊到teams表中
INSERT INTO teams(teamno,playerno,division)
VALUES(3,6,‘third’); ##需要一一對應,順序一致

3.在表名後面省略所有的列名
這種寫法要求VALUES子句中的值必須按照列在表結構中的順序來一一賦值
示例:INSERT INTO teams
VALUES(4,104,‘third’);在這裏插入圖片描述
4.在表名後面只列出部分的列名
所有沒有明確賦值的列,將通過隱式賦值自動得到null值
示例: 添加一個新球員
INSERT INTO players(playerno,NAME,initials,sex,joined,street,town)
VALUES(611,‘Jones’,‘GG’,‘M’,1997,‘Green Way’,‘Stratford’);

5.使用字面量NULL給列賦空值
示例:
INSERT INTO teams
VALUES(4,104,null); ##注意null值不要加引號

  1. VALUES子句中除了字面量,還可以使用函數、計算、標量子查詢等
    示例:
    CREATE TABLE totals(
    numberplayers INTEGER NOT NULL,
    sumpenalties DECIMAL(9,2) NOT NULL); ##創建表
    INSERT INTO totals(numberplayers,sumpenalties)
    VALUES((SELECT count(*) FROM players), ##子查詢的值必須是一行一列
    (SELECT sum(amount) FROM penalties));
    注意:子查詢必須放在單獨的小括號中在這裏插入圖片描述
    7.一條INSERT語句可以插入多個行
    示例:添加4個新的球隊
    INSERT INTO teams(teamno,playerno,division)
    VALUES (6,7,‘third’),
    (7,27,‘fourth’),
    (8,39,‘fourth’),
    (9,112,‘sixth’);
    注意:這種語法只要有一行出錯,則插入全部取消在這裏插入圖片描述8.INSERT語句中可以使用IGNORE選項來當INSERT語句出錯時,不顯示錯誤消息。INSERT語句不會執行在這裏插入圖片描述主鍵列不允許數據重複

9.帶子查詢的insert語句
帶子查詢的INSERT語句
INSERT [INTO] tbl_name[(col_name,…)]
SELECT … ##select可以非常複雜,添加where條件等
語法:如果在表名後面列出了列名,那麼列的數量和數據類型必須和子查詢的select列表相匹配
示例:insert into stu_bak select sid,sname,aphonum from stu;在這裏插入圖片描述語句釋義:stu_bak和stu表的數據類型和列的數量完全一致
Duplicates表示主鍵衝突的列:(主鍵衝突是主鍵上有重複的數據)
Records:表是插入多少行數據
示例2:
INSERT INTO penalties
SELECT paymentno + 100,playerno,payment_date,amount
FROM penalties
WHERE amount > (SELECT avg(amount) ##無關子查詢(因爲沒有where條件,沒有對外表訪問)
FROM penalties);
語句釋義:把那些罰款額大於平均罰款額的所有罰款添加到penalties表中
也可以把本表中的行再次添加到本表中。注意主鍵值不要重複

UPDATE語句
1.可以修改表中的數據
語法:
UPDATE [IGNORE] table_reference(表名)
SET col_name1=expr1 [, col_name2=expr2,],…
[WHERE where_condition]
[ORDER BY …]
[LIMIT row_count]
將滿足WHERE條件的所有行的一個或多個列值改爲新的值。沒有WHERE子句則修改所有的行
2.在寫update語句之前,可以先把select語句列出來需要更新的數據,對比着寫出update語句
示例:
例1: 把95號球員的聯盟會員號碼改爲2000
UPDATE players ##表名
SET leagueno = 2000 ##指定哪些列需要更新和更新的數據
WHERE playerno = 95; ##指定哪些行需要更新
共 1 行受到影響

例2: 把所有的罰款增加5%
UPDATE penalties
SET amount = amount*1.05;
共 8 行受到影響

例3: 把住在Stratford的球員的獲勝局數設爲0
UPDATE matches
SET won = 0
WHERE playerno IN(SELECT playerno
FROM players
WHERE town=‘Stratford’);
共 4 行受到影響在這裏插入圖片描述釋義:先寫出他們的select語句,對比寫出update語句

3.update的其他寫法(畫圖法)
通過畫圖的方法寫update語句更容易理解
案例分析
CREATE TABLE players_data(
playerno INTEGER NOT NULL PRIMARY KEY,
number_mat INTEGER,
sum_penalties DECIMAL(7,2) ## 新建表,有三列
); ##新建表的每一列來自不同表的列中的數據(或者數據操作)

INSERT INTO players_data(playerno) ##從PLAYERS表中取出數據插入到新建表中
SELECT playerno FROM players; ##新建表的第一列數據已經插入完畢

UPDATE players_data pd ##更新,將新建表的第一列數據分別訪問matches 表
SET number_mat = (
SELECT count(*)
FROM matches m
WHERE m.playerno = pd.playerno), ##number_mat列更新的數據爲多表連接後行數
sum_penalties = (
SELECT sum(amount)
FROM penalties pen
WHERE pen.playerno = pd.playerno); ##sum_penalties表更新的數據爲多表連接後的總數
語句釋義:創建表players_data保存每個球員的編號、所參加比賽的次數,和所引起的罰款總數

4.update的注意事項
注意,在SET子句的子查詢中,不允許訪問要更新的表
案例分析
在每筆罰款中減去平均罰款額。以下寫法不允許
UPDATE penalties
SET amount = amount - (SELECT avg(amount)
FROM penalties); ##set後,不允許出現要更新的表
錯誤代碼: 1064

面對這種情況,我們可以使用變量的方法進行更新
SET @avg_amount := (SELECT avg(amount) FROM penalties); ##設置變量

UPDATE penalties
SET amount = amount - @avg_amount; ##使用變量

5.update語句中的order by 語句
UPDATE語句中可以使用ORDER BY子句,要求以排序的順序來依次更新行。這在某些場景可能有用。例如,如果想要把所有罰款的罰款編號都加1,如果從罰款編號爲1的行開始更新,要麼就會發生主鍵值重複異常。如果從罰款編號最大的行開始更新,就沒有問題
update語句是先找數據,在進行更新

示例:
UPDATE penalties
SET paymentno = paymentno + 1
ORDER BY paymentno DESC; ##降序排列後加1
語句釋義:把所有罰款的編號增加1

6.update語句中的limit語句
UPDATE語句中可以使用LIMIT子句,指定一次更新的行數

示例:
UPDATE penalties
SET amount= amount *1.05
ORDER BY amount DESC, playerno ASC ##對penalties表的數據進行排序
LIMIT 4; ##前4個
語句釋義:把4個最高的罰款額增加5%(罰款額相同則更新編號小的球員)

補充:IGNORE選項用於當UPDATE語句出錯時,不顯示錯誤消息

7.update更新多個表中的值
更新多個表中的值
MySQL允許我們使用1條UPDATE語句就更新兩個或多個表中的行
語法:
UPDATE [IGNORE] table_references
SET col_name1=expr1 [, col_name2=expr2,],…
[WHERE where_condition]
其中, table_references可以使用任何合法的連接語法。不能使用ORDER BY和LIMIT子句

示例:
UPDATE matches m,teams t
SET m.won = 0,
t.playerno = 112
WHERE t.teamno = m.teamno
AND t.division = ‘first’;
語句釋義:把一個first分級球隊的所有比賽的獲勝局數設爲0,並把first分級球隊的隊長編號改爲112
可以先使用select查看我們需要更改的數據(將兩個表共有的且符合條件的顯示出來)在這裏插入圖片描述補充:MySQL首先執行一個二表連接查詢,從兩個表中找到滿足連接條件 t.teamno = m.teamno 的所有行,然後對這些行分別進行更新
使用一條語句更新多個表的優點是:要麼兩個表都更新,要麼兩個表都不更新

REPLACE語句
1.語句定義及語法
作用:替代已有的行
REPLACE語句是INSERT語句的一個變種。當添加新行時,如果主鍵值重複,那麼就覆蓋表中已有的行。如果沒有主鍵值重複,則插入該行
語法:
REPLACE [INTO] tbl_name [(col_name,…)]
VALUES (expr,…),(…),…
或者
REPLACE [INTO] tbl_name [(col_name,…)]
SELECT …

示例:
REPLACE INTO players(playerno,NAME,initials,
sex,joined,street,town)
VALUES(611,‘john’,‘GG’,‘M’,1977,‘Green Way’, ‘Startford’);
語句釋義: 添加一個新的球員。如果主鍵值已經存在,則覆蓋該行

DELETE語句
1.delete說明及語法
delete語句只能一行一行的刪,只能刪除整行,不能刪除某一行的某些列
語法:
DELETE [IGNORE] FROM tbl_name
[WHERE where_condition]
[ORDER BY …]
[LIMIT row_count]
從表中刪除滿足WHERE條件的所有行。沒有WHERE條件,則刪除表中的所有行

示例:
DELETE FROM penalties
WHERE playerno=44;
語句釋義:刪除44號球員的罰款

2.帶子查詢
注:在WHERE子句的子查詢中,不允許訪問要刪除行的表
案例分析:
CREATE TABLE players_copy2
AS SELECT * FROM players; ##因爲在WHERE子句的子查詢中,不允許訪問要刪除行的表,所以我們可以創建一張和PLAYERS表一樣的表

DELETE FROM players_copy1
WHERE joined > (
SELECT avg(joined)
FROM players_copy2 ## players_copy2 表和PLAYERS表一樣
WHERE town = ‘Stratford’);
語句釋義: 刪除球員,條件是他們加入俱樂部的年份晚於來自於Stratford的球員加入俱樂部的平均年份
補充:面對較爲複雜的刪除,我們可以先用select語句將我們要刪除的球員列出來,再將select *替換爲delete即可

3.帶ORDER BY子句和LIMIT子句
用在DELETE語句中的ORDER BY子句和LIMIT子句的含義和用在UPDATE語句中是類似的
示例:
DELETE FROM penalties
ORDER BY amount DESC,playerno ASC
LIMIT 4;
語句釋義:刪除4個最高的罰款

4.從多個表中刪除行
語法:
DELETE [IGNORE] tbl_name[.] [, tbl_name[.]] …
FROM table_references
[WHERE where_condition]
如果FROM中的表有別名,在DELETE子句中只能使用表別名
示例:
DELETE teams, matches
FROM teams, matches
WHERE teams.teamno = matches.teamno
AND teams.teamno=3;
語句釋義:從teams和matches表中刪除所有3號球隊的行; 兩個表中滿足連接條件teams.teamno = matches.teamno和過濾條件teams.teamno=3的所有行被刪除

TRUNCATE語句
清空一張(大)表更有效的方法是使用TRUNCATE語句,它比DELETE快得多
原理:將錶行尾的指針直接指向0,這樣mysql認爲該表數據已經清空,真實數據未清空,mysql後臺程序或自動清理代表的數據
語法:
TRUNCATE [TABLE] tbl_name
示例:
Truncate table committee_members; ##將committee_members表清空

事務
1.事務:transaction
一個數據庫事務由一條或者多條sql語句構成,它們形成一個邏輯的工作單元。這些sql語句要麼全部執行成功,要麼全部執行失敗
事務是保證數據的完整性和一致性的重要手段
事務類型
DML事務:由一條或者多條DML語句構成
DDL事務:總是由一條DDL語句構成
DCL事務:總是由一條DCL語句構成

2.在MySQL中,系統變量@@autocommit默認是打開的,這意味着任何1條SQL語句都會開始一個事務,語句執行完後事務自動結束。實際使用中,應該使用SET語句來關閉自動提交,否則一個事務不可能由多條SQL語句構成
SHOW VARIABLES LIKE ‘%autocommit%’;
SET @@autocommit=0;
SHOW VARIABLES LIKE '%autocommit%’;

3.對於DDL(create、alter、drop等開頭的語句)和DCL(grant、revoke語句)事務,在執行每條語句之前和之後,MySQL會自動執行一條COMMIT語句,因此事務是自動開始和結束的。自動提交打開或者關閉對這些事務沒有影響
對於DML事務,在自動提交關閉的情況下,事務的開始分爲隱式開始和顯式開始:
隱式開始:程序的第一條DML語句執行時或者在COMMIT或ROLLBACK語句之後執行第一條DML語句時,自動開始一個新的事務
顯式開始:發出STRAT TRANSACTION語句。該語句會自動關閉自動提交,當事務結束後,autocommit變量恢復到原來的值

4.DML事務的結束
COMMIT語句:成功提交。事務所做的全部工作被永久地保存到磁盤上
ROLLBACK語句:失敗回滾。事務所做的全部工作被撤銷,表中的數據不受事務操作的影響
其它事務控制語句
SAVEPOINT identifier :保存點命令,用來在事務中做一個標記,專門提供給rollback to語句使用
ROLLBACK TO [SAVEPOINT] identifier:回滾到保存點。專門用來撤銷事務所做的部分工作:保存點之後所做的工作全部撤銷。該語句並不結束事務

5.事務示例在這裏插入圖片描述ROLLBACK TO b; ##回滾到a保存點
ROLLBACK TO a; ##回滾到b保存點
ROLLBACK; ##回滾到事務開始之前

6.COMMIT 或 ROLLBACK 語句之前數據的狀態
數據的修改都是在內存中進行的
通過查詢表,當前用戶(事務)能夠查看DML操作的結果
其它用戶(事務)不能查看當前用戶(事務)所做的DML操作的結果。這叫做不允許髒讀(dirty read)。髒讀:一個事務讀到了另一個事務未提交的數據。已修改但未提交的數據叫做贓數據
表中受影響的行被鎖定,其它用戶(事務)不能在受影響的行上修改數據

7.COMMIT或ROLLBACK語句之後數據的狀態
COMMIT之後:
數據改變被寫到數據庫中
所有用戶(事務)可以查看事務的結果
表中受影響行上的鎖被釋放,這些行現在可以被其它用戶(事務)修改
事務中所有的保存點被刪除
ROLLBACK之後:
數據改變被撤銷
數據先前的狀態被恢復
表中受影響行上的鎖被釋放

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章