正如其他答案所闡述的,automincrement
不可用作解決問題的工具。
你可以做什麼
(上幾乎一模一樣的表架構,只是一個額外的UNIQUE
爲端口列)
是添加觸發器和「harcoded」虛擬線。
是實現什麼(與我提出以下,但在細節上可以適應任何規則適用於港口在你的數據庫中的使用率觸發):(> 8080)
- 輸入一個有效的和未使用的端口號
它被輸入到數據庫中
- 輸入無效(< 8080)端口號
它就會以最低的,有效的,未使用的一個替代,
即使存在由特定端口號的差距 前挑選
- 刪除數據庫條目,
端口號到達以後
- 重複使用輸入已使用的端口號
導致「獨特的失敗」(如不進入您的設置已使用的客戶域)
- 爲在腳本中使用,你可以跳過端口號
的所有的計算,而是
- 允許portnumbers的輸入(數據庫將防止雙打)
- 只是一直用「1」的端口號(數據庫會發現適合的)
有一點要牢記:
每當你讀出的列表中,你需要以某種方式忽略虛擬線。
代碼:
CREATE TRIGGER autoport AFTER INSERT ON cusports
BEGIN
UPDATE cusports
SET port=
(SELECT MIN(a.port+1)
FROM
(SELECT * FROM cusports WHERE port >=8080)
AS a
LEFT JOIN
cusports AS b
ON a.port+1 = b.port
WHERE b.port IS NULL)
WHERE port<8080;
END;
INSERT INTO cusports(cus_id, cus_name, cus_domain, cus_status, Port)
VALUES(NULL,'dummycusname','dummycusdomain','dummycusstatus',8080);
詳情:
- 我建立對草莓的答案
Returning the lowest integer not in a list in SQL
(SELECT * FROM cusports WHERE port >=8080)
,而不是簡單的cusports
,
爲了不使用 可能無效的新插入端口號
SELECT MIN(a.port+1)
查找最小端口號是「比現有的更高1,無需現有本身」(中斜體部分是由草莓)
WHERE port<8080
限制更新爲僅無效端口號
(不想搞砸了現有條目)
- 啞線用於對不實際上是尋找所有不存在的號碼草莓方法的根源,但只列出「一個比現有更高的」
測試與輸出(SQLite的命令行工具,後設置觸發器和啞線在一個空表):
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
sqlite> insert into cusports values (null, 'cusa', 'doma', 'stata', 8081);
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
sqlite> insert into cusports values (null, 'cusb', 'domb', 'statb', 8083);
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
3 cusb domb statb 8083
sqlite> -- note the 8082 gap and the following invalid '1'
sqlite> insert into cusports values (null, 'cusc', 'domc', 'statc', 1);
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
3 cusb domb statb 8083
4 cusc domc statc 8082
sqlite> insert into cusports values (null, 'cusd', 'domd', 'statd', 1);
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
3 cusb domb statb 8083
4 cusc domc statc 8082
5 cusd domd statd 8084
sqlite> delete from cusports where port=8083;
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
4 cusc domc statc 8082
5 cusd domd statd 8084
sqlite> insert into cusports values (null, 'cuse', 'dome', 'state', 1);
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
4 cusc domc statc 8082
5 cusd domd statd 8084
6 cuse dome state 8083
sqlite> insert into cusports values (null, 'cuse', 'dome', 'state', 1);
Error: UNIQUE constraint failed: cusports.cus_domain
sqlite> insert into cusports values(null, 'cusf', 'domf', 'statf', 8083);
Error: UNIQUE constraint failed: cusports.Port
sqlite> select * from cusports;
cus_id cus_name cus_domain cus_status Port
---------- ------------ -------------- -------------- ----------
1 dummycusname dummycusdomain dummycusstatus 8080
2 cusa doma stata 8081
4 cusc domc statc 8082
5 cusd domd statd 8084
6 cuse dome state 8083
完全.dump
供參考(爲便於閱讀,一些希望正確換行符):
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE cusports(
cus_id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
cus_name TEXT NOT NULL UNIQUE,
cus_domain TEXT UNIQUE,
cus_status TEXT NOT NULL,
Port INTEGER NOT NULL UNIQUE);
INSERT INTO cusports(cus_id,cus_name,cus_domain,cus_status,Port)
VALUES(1,'dummycusname','dummycusdomain','dummycusstatus',8080);
INSERT INTO cusports(cus_id,cus_name,cus_domain,cus_status,Port)
VALUES(2,'cusa','doma','stata',8081);
INSERT INTO cusports(cus_id,cus_name,cus_domain,cus_status,Port)
VALUES(4,'cusc','domc','statc',8082);
INSERT INTO cusports(cus_id,cus_name,cus_domain,cus_status,Port)
VALUES(5,'cusd','domd','statd',8084);
INSERT INTO cusports(cus_id,cus_name,cus_domain,cus_status,Port)
VALUES(6,'cuse','dome','state',8083);
DELETE FROM sqlite_sequence;
INSERT INTO sqlite_sequence(name,seq) VALUES('cusports',7);
CREATE TRIGGER autoport AFTER INSERT ON cusports
BEGIN
UPDATE cusports
SET port=
(SELECT MIN(a.port+1)
FROM
(SELECT * FROM cusports WHERE port >=8080)
AS a
LEFT JOIN
cusports AS b
ON a.port+1 = b.port
WHERE b.port IS NULL)
WHERE port<8080;
END;
COMMIT;
請解釋區別到https://stackoverflow.com/questions/44644895/how-can-i-define-the-insert-query-with-unique-constraint爲什麼你不編輯這個問題? – Yunnosch
我在for循環之前定義了port_num = 8080,然後在for循環中我定義了「port_number = $ port_num」「port_number = $((port_number + 1))」,但是在循環內部端口號不增加。我爲增加端口號碼值而執行循環..? – Mahendranatarajan
@雲諾斯請修復我的要求 – Mahendranatarajan