Sqlite3中replace語句用法詳解

2021-07-23 16:57:29 字數 3483 閱讀 9856

由於自己的孤陋寡聞, 也由於之前的專案中, 很少參與過資料庫模組的開發, 以至於前幾天才知道sqlite資料庫也支援replace語句。 本文主要講解在sqlite中replace語句的行為,也算是學習筆記。此外, replace語句和update語句有相似的地方, 但是也有很多不同之處。 本文還要對比一下sqlite中的 replace語句和update語句 。

在本例中使用如下資料庫表:

(圖 1)

該錶的表名為student, 儲存學生資訊。 所有欄位的資料型別都是text 。 其中id和name作為復合主鍵。 email欄位加上了唯一約束。建表語句如下:

create table if not exists student (

"id" text,

"name" text not null,

"***" text,

"email" text unique,

"fenshu" text check(fenshu > 0),

"tecid" text references teacher(id),

"class" text,

primary key(id, name)

)

為了驗證這個結論, 下面開啟sqlite命令列, 執行以下語句來替換id為2的記錄。

sqlite> replace into student (id, name, ***, email, fenshu, tecid, class) values

('2', 'lisi', '*f', '[email protected]', '80', '2', '1');

執行完這條語句之後, student表中的資料變成下圖所示:

(圖 2)

對比圖1和圖2 , 可以發現: 在圖1中, id為2 的記錄是表中的第一條記錄, 當執行完上述的replace語句之後, id為2的記錄位於整張表的最後。 這就說明, 這條replace語句刪除了原有的id為2的記錄, 有插入了一條新的id為2的記錄。

下面我們還是以id為2 的記錄做實驗, 執行如下語句:

sqlite> replace into student (id, name, ***, email, fenshu, tecid) values ('2',

'lisi', '*f', '[email protected]', '80', '2');

該語句還是替換id為2, name為lisi的記錄, 只是在指定列的時候, 沒有指定class列。 在執行完成之後, 表中的資料如下:

(圖 3)

對比圖2和圖3 , 可以看到, id為2, name為lisi的記錄的class欄位沒有值。

在該表中, 把id和name指定為復合主鍵。 在上面兩條語句執行的時候, 都在values中指定了id為2, name為lisi 。 執行之後看到的結果也是id為2, name為lisi的記錄被替換。 這就說明了replace語句根據主鍵的值確定被替換的是哪一條記錄。

執行以下語句:

sqlite> replace into student (id, name, ***, email, fenshu, tecid) values ('2',

'lisi', '*f', '[email protected]', '80', '2') where id = '2';

會報如下錯誤:
error: near "where": syntax error
在student表中, 我們讓id和name成為復合主鍵。 下面我們使用replace語句替換id為100, name為a 的記錄。 從圖3中可以看到, 表中存在name為a的記錄, 但是這條記錄的id為7, 而不是100 。也就是說 id為100, name為a 的記錄不存在。

執行如下語句:

sqlite> replace into student (id, name, ***, email, fenshu, tecid, class) values

('100', 'a', '*f', '[email protected]', '80', '2', '1');

執行完成之後, 表中的資料如下:

(圖 4)

可以看到, 在表中插入了一條新的記錄。

上面的第5步同時也說明了這個問題。 對比圖4 和圖5 , 發現在插入一條新的id為100, name為a的記錄之後, 還刪除了id為2, name為lisi的記錄。 為什麼會這樣呢? 我們在開始的時候說過, 表中的email欄位加上了唯一約束。 id為2的記錄的email和新插入的id為100的記錄中的email相同, 都是[email protected] 。 這就導致違反唯一約束, 所以在插入id為100的記錄之前, 刪除了id為2的記錄。

下面再次驗證一下。 現在我們替換id為5, name為lisi3 的記錄, 將它的email替換為[email protected] 。 表中的id為5的記錄的email欄位也是[email protected] , 所以會導致違反唯一約束。

執行下面的語句:

sqlite> replace into student (id, name, ***, email, fenshu, tecid, class) values

('5', 'lisi3', 'f', '[email protected]', '80', '2', '1');

執行完這條語句之後, 表中的資料如下圖:

(圖 5)

對比圖4 和 圖5 , 發現id為5的記錄被替換掉, 並且把這條記錄的email設定為[email protected], 這和圖4中原有的id為6的記錄衝突, 所以導致id為6的記錄被刪除, 在圖5 中已經沒有id為6的那條記錄了。

對於update語句, 因為經常使用到,應該算比較熟悉。 下面對比一下update和replace語句的行為, 只是簡單陳述, 不再以具體例項說明。

update語句使用where子句定位被更新的記錄;

update語句可以一次更新一條記錄, 也可以更新多條記錄, 只要這多條記錄都復合where子句的要求;

update只會在原記錄上更新欄位的值, 不會刪除原有記錄, 然後再插入新紀錄;

如果在update語句中沒有指定一些字段, 那麼這些字段維持原有的值, 而不會被置空;

Sqlite3中replace語句用法詳解

在本例中使用如下資料庫表 圖 1 該錶的表名為student,儲存學生資訊。所有欄位的資料型別都是text 其中id和name作為復合主鍵。email欄位加上了唯一約束。建表語句如下 create table if not exists student id text,name text not n...

使用sqlite3 模組操作sqlite3資料庫

python內建了sqlite3模組,可以操作流行的嵌入式資料庫sqlite3。如果看了我前面的使用 pymysql 操作mysql資料庫這篇文章就更簡單了。因為它們都遵循pep 249,所以操作方法幾乎相同。廢話就不多說了,直接看 吧。都差不多,首先匯入模組,然後建立連線,然後獲取游標物件,之後利...

SQLite3中TimeStamp的使用問題

color blue 在使用sqlite3時使用了timestamp,但是遇到一些問題,現總結如下 一 我的sql語句 create table logs id integer primary key,idcardno varchar 50 createdtime timestamp not nul...