2017-06-22 52 views
1

在我的劇本,我想用8080我如何定義自動遞增到端口字段

#!/bin/bash 

echo " --- Enter the Database name ---" 
read databasename 


echo " --- enter the table name --- " 
read table_name 

sqlite3 $databasename.db "DROP TABLE IF EXISTS $table_name;" 

sqlite3 $databasename.db "CREATE TABLE IF NOT EXISTS $table_name(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);" 


echo " --- Enter the total number of rows do you want ---" 
read cus_count 


echo "--- Enter the following details one by one---" 

port_num=8080 

for((i=1;i<=cus_count;i++)) 
do 
port_number=$port_num 

port_number=$((port_number + 1)) 

echo "port number is $port_number" 

echo "enter the $i customer details" 

echo "---Enter the customer name---" 
read c_name 

echo "---Enter the Status(Active/Inactive)---" 
read c_status 


c_domain="$c_name" 

sqlite3 $databasename.db "INSERT OR IGNORE INTO $table_name (cus_name,cus_domain,cus_status, Port) VALUES(\"$c_name\",\"${c_domain,,}\",\"$c_status\",\"$port_number\") ;" 

done 

echo " --- Records from the $table_name ---" 

sqlite3 $databasename.db "select * from $table_name;" 

默認值來聲明端口字段列自動遞增我如何定義自動遞增到端口字段?

+0

請解釋區別到https://stackoverflow.com/questions/44644895/how-can-i-define-the-insert-query-with-unique-constraint爲什麼你不編輯這個問題? – Yunnosch

+0

我在for循環之前定義了port_num = 8080,然後在for循環中我定義了「port_number = $ port_num」「port_number = $((port_number + 1))」,但是在循環內部端口號不增加。我爲增加端口號碼值而執行循環..? – Mahendranatarajan

+0

@雲諾斯請修復我的要求 – Mahendranatarajan

回答

0

在SQLite中,autoincrementing只適用於主鍵,端口號不是PK,也不應該是。

您必須使用自己的變量來增加端口號。 (你已經在做的事情。)

的問題是,你正在使用兩個變量:

for((i=1;i<=cus_count;i++)) 
do 
port_number=$port_num 
port_number=$((port_number + 1)) 

你遞增port_number,但其重置爲在每次循環的舊值(port_num)。

在循環之前,您應該只讀一次port_num;或使用單個變量;或者將新值寫回另一個變量。

0

正如其他答案所闡述的,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; 
+0

它顯示錯誤meassage「錯誤:沒有這樣的表:main.cusports」 – Mahendranatarajan

+0

什麼是在你的數據庫中調用表?您可能必須使用腳本中的相應變量,或更改腳本以使用相同的固定表名稱。我正在使用純SQLite。 – Yunnosch

+0

如何更改。我只使用固定表名稱 – Mahendranatarajan