1. 程式人生 > >4 資料更新

4 資料更新

 

4 資料更新

4-1 資料的插入(INSERT語句的使用方法)

 

通過create table語句創建出來的表,可以將其比作一個空空如也的箱子。只有把資料裝入到這個箱子後,它才能稱為資料庫。用來裝入資料的SQL就是INSERT(插入)。

 

什麼是INSERT

CREATE TABLE shohinIns (

shohin_id CHAR(4) NOT null,

shohin_mei VARCHAR(100) NOT NULL,

shohin_bunrui VARCHAR(32) NOT NULL,

hanbai_tanka INTEGER DEFAULT 0,

shiire_tanka INTEGER,

totokubi DATE,

PRIMARY KEY (shohin_id)

);

 

 

 

 

 

INSERT語句的基本語法

-- INSERT INTO <表名> (列1,列2, 列3, 。。。) VALUES (值1,值2,值3,。。。);  包括:列清單和值清單(兩者數量必須保持一致)

 

INSERT INTO shohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, totokubi)

VALUES ('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');

 

列名和值用逗號隔開,分別括在()內,這種形式稱為清單。

 

法則4-1

原則上,執行一次INSERT語句會插入一行資料。(其實很多RDBMS都支援一次INSERT多行資料,這樣的功能稱為“多行INSERT(multi row INSERT)”,一般不建議使用)。

 

 

 

 

 

 

對錶進行全列INSERT時,可以省略表名後的列清單。這時VALUES子句的值會預設按照從左到右的順序賦給每一列。

 

列清單的省略

INSERT INTO shohinIns VALUES ('0005', '高壓鍋', '廚房用具', 6800, 5000, '2009-01-15');

 

 

INSERT語句中想給某一列賦予NULL值時,可以直接在VALUES子句的值清單中寫入NULL。

但是,想要插入NULL的列一定不能設定NOT NULL約束。向設定了NOT NULL約束的列中插入NULL時,INSERT語句會出錯,資料插入失敗。

插入失敗指的是希望通過INSERT語句插入的資料無法正常插入到表中,但之前已經插入的資料並不會被破壞。

 

插入NULL

INSERT INTO shohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, totokubi)

VALUES ('0006', '叉子', '廚房用具', 500, NULL, '2009-09-20');

 

 

 

通過顯式方法插入預設值(初始值),預設值的設定,可以通過在建立表的CREATE TABLE語句中設定DEFAULT約束來實現。

 

在VALUES子句中指定DEFAULT關鍵字(顯示方式插入預設值);

 

通過隱式方式插入預設值,插入預設值時也可以不使用DEFUALUT關鍵字(隱式方式插入預設值,即值什麼都不寫);

 

那麼,在實際使用中哪種方法更好呢?筆者建議大家使用顯示的方法。

 

說的省略列名,還有一定要說明以下。如果省略了沒有設定預設值的列的話,該列的值就會被設定為NULL。因此,如果省略的是設定了NOT NULL約束的列的話,INSERT語句就會出錯。

 

插入預設值

INSERT INTO shohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, totokubi)

VALUES ('0007', '擦菜飯', '廚房用具', DEFAULT, 790, '2009-04-28');

 

SELECT * FROM shohinIns WHERE shohin_id = '0007';

 

INSERT INTO shohinIns (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, totokubi)

VALUES ('0008', '圓珠筆', '辦公用品', 100, '2009-11-11');

 

INSERT INTO shohinIns (shohin_id, shohin_bunrui, hanbai_tanka, shiire_tanka, totokubi)

VALUES ('0009', '辦公用品', 1000, 500, '2009-12-12');

 

 

法則4-2

省略INSERT語句中的列名,就會自動設定為該列的預設值(沒有預設值時會設定為NULL)。

 

 

插入資料的方法,除了使用VALUSE子句指定具體的資料之外,還可以從其他表中複製資料。

 

從其他表中複製資料

-- 用來插入資料的商品複製表

CREATE TABLE shohinCopy (

shohin_id CHAR(4) NOT null,

shohin_mei VARCHAR(100) NOT NULL,

shohin_bunrui VARCHAR(32) NOT NULL,

hanbai_tanka INTEGER,

shiire_tanka INTEGER,

torokubi DATE,

PRIMARY KEY (shohin_id)

);

 

-- 將商品表中的資料複製到商品複製表中

INSERT INTO shohinCopy (shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi)

SELECT shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi FROM shohin;

 

-- 用來彙總商品種類的表

CREATE TABLE shohinBunrui (

shohin_bunrui VARCHAR(32) NOT NULL,

sum_hanbai_tanka INTEGER,

sum_shiire_tanka INTEGER,

PRIMARY KEY (shohin_bunrui)

);

 

INSERT INTO shohinBunrui (shohin_bunrui, sum_hanbai_tanka, sum_shiire_tanka) SELECT shohin_bunrui,

SUM(hanbai_tanka), SUM(shiire_tanka) FROM shohin GROUP BY shohin_bunrui;

 

SELECT * FROM shohinBunrui;

 

 

法則4-3

INSERT語句的SELECT語句中,可以使用WHERE子句或者GROUP BY 子句等任何SQL語法(但使用ORDER BY子句並不會產生任何效果)

 

 

 

 

4-2 資料的刪除(DELETE語句的使用方法)

 

刪除資料的方法,大體可以分為以下兩種 :

第一, DROP TABLE語句可以將表完全刪除,因此刪除之後再想插入資料,就必須使用CREATE TABLE語句重新建立一張表。

第二, DELETE語句會留下表(容器),而刪除表中的全部資料,因此只需要通過INSERT語句就可以再次向表中插入資料。

 

只能刪除表中全部資料的TERUNCASE語句   TRUNCASE <表名>;

與delete不同的是,truncate只能刪除表中的全部資料,而不能通過where子句指定條件來刪除部分資料。也正是因為它不能具體地控制刪除物件,所以其處理速度比delete要快的多。

 

DELETE語句的基本語法

-- DELETE FROM <表名>;

DELETE FROM shohin;

 

由於DELETE語句的物件是行而不是列,所以DELETE語句無法只刪除部分列的資料。因此,在DELETE語句中指定列名是錯誤的。當然,使用星號的寫法也是不對的(DELETE * FROM shohin;),同樣會出錯。

 

法則4-4

DELECT語句的刪除物件並不是表或者列,而是記錄(行)。

 

 

 

 

想要刪除部分資料行時,可以像SELECT語句那樣使用WHERE子句指定刪除條件。這種指定了刪除物件的DELETE語句稱為搜尋型DELETE.

 

指定刪除物件的DELETE語句(搜尋型DELECT)

-- DELETE FROM <表名> WHERE <條件>;

 

DELETE FROM shohin WHERE hanbai_tanka >= 4000;

 

與SELECT語句不同的是,DELETE語句中不能使用GROUP BY、HAVING和ORDER BY三類子句,而只能使用WHERE子句。原因很簡單,GROUP BY和HAVING是從表中選取資料時用來改變抽取資料形式的,而ORDER BY是用來指定取得結果顯示順序的。因此,在刪除表中資料時它們都起不到什麼作用。

 

法則4-5

可以通過WHERE子句指定物件條件來刪除部分資料。

 

 

 

 

4-3 資料的更新(UPDATE語句的使用方法)

 

 

UPDATE語句的基本語法

-- UPDATE <表名> SET <列名> = <表示式>;

 

UPDATE shohin SET torokubi = '2009-10-10';

 

SELECT * FROM shohin ORDER BY shohin_id;

 

將更新物件的列和更新後的值都記述在SET子句中。

 

更新資料時也可以像DELETE語句那樣使用WHERE子句。這種指定更新物件的UPDATE語句稱為搜尋型UPDATE語句。

 

指定條件的UPDATE語句(搜尋型UPDATE)

-- UPDATE <表名> SET <列名> = <表示式> WHERE <條件>;

 

UPDATE shohin SET hanbai_tanka = hanbai_tanka * 10 WHERE shohin_bunrui = '廚房用具';

 

SELECT * FROM shohin ORDER BY shohin_id;

 

 

 

使用UPDATE也可以將列更新為NULL(該更新俗稱為NULL清空)。

 

使用NULL進行更新

UPDATE shohin SET torokubi = NULL WHERE shohin_id = '0008';

 

SELECT * FROM shohin ORDER BY shohin_id;

 

和INSERT語句一樣,UPDATE語句也可以將NULL作為一個值來使用。

但是,只有未設定NOT NULL約束和主鍵約束的列才可以清空為NULL。如果將設定了上述約束的列更新為NULL,就會出錯,這點與INSERT語句相同。

 

法則4-6

使用UPDATE語句可以將值清空為NULL(但只限於未設定NOT NULL約束的列)。

 

 

 

UPDATE語句的SET子句支援同時將多個列作為更新物件。

 

多列更新

-- 使用逗號將列分隔排列

UPDATE shohin SET hanbai_tanka = hanbai_tanka * 10 WHERE shohin_bunrui = '廚房用具';

 

-- 將列用()括起來的列表形式

UPDATE shohin SET shiire_tanka = shiire_tanka / 2 WHERE shohin_bunrui = '廚房用具';

 

-- 建議使用這一種,使用逗號將列進行分隔排序的方法,這是通用的

UPDATE shohin SET hanbai_tanka = hanbai_tanka * 10,  shiire_tanka = shiire_tanka / 2 WHERE shohin_bunrui = '廚房用具';

-- 部分dbms不支援下面這種寫法

UPDATE shohin SET (hanbai_tanka, shiire_tanka) = (hanbai_tanka * 10, shiire_tanka / 2) WHERE shohin_bunrui = '廚房用具';

 

 

4-4 事務

 

在RDBMS中,事務代表了對錶中資料進行更新的單位。簡單來講,事務就是需要在同一個處理單元中執行的一系列更新處理的集合。

 

4-7

事務是需要在同一個處理單元中執行的一系列更新處理的集合。

 

一個事務中包含多少個更新處理或者包含哪些處理,在DBMS中並沒有固定的標準。

 

 

使用事務開始語句和事務結束語句,將一系列DML語句(INSERT/UPDATE/DELETE語句)括起來,就實現了一個事務處理。

 

建立事務

/*

事務開始語句;

   DML語句1;

   DML語句2;

   DML語句3;

   .

    .

   .

事務結束語句(COMMIT或者ROLLBACK);

 

SQL server   /    PostgreSQL

BEGIN TRANSACTION

 

mysql

START TRANSACTION

 

oracle   /   DB2

 

*/

 

 

-- SQL server   postgresql

BEGIN TRANSACTION;

UPDATE shohin SET hanbai_tanka = hanbai_tanka - 1000 WHERE shohin_mei = '運動T恤';

   UPDATE shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫';

COMMIT;

 

-- mysql

START TRANSACTION;

   UPDATE shohin SET hanbai_tanka = hanbai_tanka - 1000 WHERE shohin_mei = '運動T恤';

   UPDATE shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫';

COMMIT;

 

-- oracle db2

UPDATE shohin SET hanbai_tanka = hanbai_tanka - 1000 WHERE shohin_mei = '運動T恤';

UPDATE shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫';

COMMIT;

 

/*

各個dbms事務的開始語句都不盡相同。其中Oracle和DB2並沒有定義特定的開始語句。

可能大家覺得這樣設計很巧妙,其實是因為標準sql中規定了

一種悄悄開始事務處理的方法。因此,即使經驗豐富的工程師也經常忽略事務處理開始的時點。

 

*/

 

-- SQL server   postgresql

BEGIN TRANSACTION;

UPDATE shohin SET hanbai_tanka = hanbai_tanka - 1000 WHERE shohin_mei = '運動T恤';

   UPDATE shohin SET hanbai_tanka = hanbai_tanka + 1000 WHERE shohin_mei = 'T恤衫';

ROLLBACK;

 

COMMIT是提交事務包含的全部更新處理的結束指令。相當於檔案處理中的覆蓋儲存。一旦提交,就無法恢復到事務開始前的狀態了。因此,在提交之前一定要確認是否真的需要進行這些更新。

萬一由於誤操作提交了包含錯誤更新的事務,就只能重新回到重新建表、重新插入資料這樣繁瑣的老路上了。由於可能會造成無法恢復的後果,請大家一定要注意(特別是在執行DELETE語句的COMMIT時尤其小心)。

 

ROLLBACK是取消事務包含的全部更新處理的結束命令。相當於檔案處理中的放棄儲存。一旦回滾,資料庫就會回覆到事務開始之前的狀態。通常回滾並不會像提交那樣造成大規模的資料損失。

 

 

法則4-8

雖然我們可以不清楚事務開始的時點,但是在事務結束時一定要仔細進行確認。

 

 

DBMS的事務都遵循四種標準規格的約定。將這四種特定的首字母結合起來統稱為ACID特性。這些約定是所有DBMS都必須遵守的規則。

 

ACID特性

原子性是指在事務結束時,其中所包含的更新處理要麼全部執行,要麼完全不執行的特性。也就是要麼佔有一切要麼一無所有。從事務中途停止的角度去考慮,就能比較容易理解原子性的重要性了。由於使用者在一個事務中定義了兩條UPDATE語句,DBMS肯定不會只執行其中一條,否則就會對業務處理造成影響。

 

一致性指的是事務中包含的處理,要滿足資料庫提前設定的約束,如主鍵約束或者not null約束等。對事務來說,這些不合法的SQL會被回滾。也就是說這些SQL處理會被取消,不會執行。一致性也稱完整性。

 

隔離性指的是保證不同事務之間互不干擾的特性。該特性保證了事務之間不會互相巢狀。此外,在某個事務中進行的更改,在該事務結束之前,對其他事務而言是不可見的。因此,即使某個事務向表中添加了記錄,在沒有提交之前,其他事務是看不到新新增的記錄的。

 

永續性也可以稱為耐久性,指的是事務(不論是提交還是回滾)一旦結束,dbms會保證該時點的資料狀態得以儲存的特性。即使由於系統故障導致資料丟失,資料庫也一定能通過某種手段進行恢復。如果不能保證永續性,即使是正常提交結束的事務,一旦發生了系統故障,就會導致資料丟失,一切都需要從頭再來的後果。保證永續性的方法根據實現的不同而不同,其中最常見的就是將事務的執行記錄儲存到硬碟等儲存介質中(該執行記錄稱為日誌)。當發生故障時,可以通過日誌恢復到故障發生的狀態。