mysql筆記之插入&鍵值重複解決
阿新 • • 發佈:2018-12-17
建立表並插入資料
create table t select_info;
MariaDB [test]> create table t2 select user,host password from mysql.user where user='root'; MariaDB [test]> select * from t2; +------+-------------+ | user | password | +------+-------------+ | root | 127.0.0.1 | | root | ::1 | | root | localhost | | root | zabbix\_ser | +------+-------------+ 4 rows in set (0.00 sec)
create table t as select_info
MariaDB [test]> create table t3(user char(20),host char(20),password char(50)) as select user,host,password from mysql.user where user='root'; Query OK, 4 rows affected (0.01 sec) Records: 4 Duplicates: 0 Warnings: 0 MariaDB [test]> select * from t3; +------+-------------+-------------------------------------------+ | user | host | password | +------+-------------+-------------------------------------------+ | root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | | root | zabbix\_ser | | | root | 127.0.0.1 | | | root | ::1 | | +------+-------------+-------------------------------------------+ 4 rows in set (0.00 sec)
這些語句檢索資料,並按照檢索目標欄位新建一張表,表必須不能已經存在,除非使用or replace或者if not exists子句
只建立表結構,不插入資料:
create table t1 like t2 --建立完全相同的表結構
create table tbl_name1 select v1,v2,v3 from t2 where 1=0; # where false。--可以篩選部分欄位作為新表的結構
鍵值重複
使用ignore關鍵字忽略所有錯誤行,使insert操作繼續插入後面的資料。 使用insert ... on duplicate key update,將有重複值的行update為新的值。 使用replace into語句替代insert into語句,將有重複值的行替換為新行
ignore
準備測試環境
MariaDB [test]> insert into t4 values
-> (1,'man','zs'),
-> (2,'man','ls'),
-> (3,'man','ww'),
-> (4,'women','xh'),
-> (5,'women','xl'),
-> (6,'women','xb'),
-> (7,'man','ld'),
-> (8,'women','hj'),
-> (9,'men','lk');
Query OK, 9 rows affected (0.00 sec)
Records: 9 Duplicates: 0 Warnings: 0
MariaDB [test]> select * from t4;
+----+-------+------+
| id | sex | name |
+----+-------+------+
| 1 | man | zs |
| 2 | man | ls |
| 3 | man | ww |
| 4 | women | xh |
| 5 | women | xl |
| 6 | women | xb |
| 7 | man | ld |
| 8 | women | hj |
| 9 | men | lk |
+----+-------+------+
9 rows in set (0.00 sec)
插入資料
MariaDB [test]> insert into t4 values(5,'women','lw'),(10,'man','sg');
ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'
MariaDB [test]> select * from t4 where id=5 or id=10;
+----+-------+------+
| id | sex | name |
+----+-------+------+
| 5 | women | xl |
+----+-------+------+
1 row in set (0.00 sec)
使用ignore關鍵字
MariaDB [test]> insert ignore into t4 values(5,'yao','lll'),(10,'ttt','666');
Query OK, 1 row affected, 1 warning (0.00 sec)
Records: 2 Duplicates: 1 Warnings: 1
MariaDB [test]> select * from t4 where id=5 or id=10;
+----+-------+------+
| id | sex | name |
+----+-------+------+
| 5 | women | xl |
| 10 | ttt | 666 |
+----+-------+------+
2 rows in set (0.00 sec)
使用 on duplicate key update子句修改重複值記錄
兩種情況:
1.插入的記錄沒有鍵值衝突
帶不帶都無所謂了
2.插入的記錄有鍵值重複衝突
帶有 on duplicate key update 子句會更新表中原有的記錄
測試
MariaDB [test]> select * from t5; ±—±-----±-----+ | id | sex | name | ±—±-----±-----+ | 1 | xx | qq | | 2 | xx | ww | | 3 | yy | ee | ±—±-----±-----+ 3 rows in set (0.00 sec)
插入的記錄沒有鍵值衝突
MariaDB [test]> insert into t5 values(4,'xx','rr'),(5,'yy','tt');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
插入的記錄有鍵值重複衝突
MariaDB [test]> insert into t5 values(4,'xx','rrrr'),(6,'yy','yy') on duplicate key update name='rrrr';
Query OK, 3 rows affected (0.00 sec)
Records: 2 Duplicates: 1 Warnings: 0
MariaDB [test]> select * from t5;
+----+------+------+
| id | sex | name |
+----+------+------+
| 1 | xx | qq |
| 2 | xx | ww |
| 3 | yy | ee |
| 4 | xx | rrrr |
| 5 | yy | tt |
| 6 | yy | yy |
+----+------+------+
6 rows in set (0.00 sec)
還可以在update子句中利用函式 VALUES(col_name)引用insert 部分列值
MariaDB [test]> insert into t5 values(4,'xx','rrrr') on duplicate key update name=concat('yy',values(id));
Query OK, 2 rows affected (0.08 sec)
MariaDB [test]> select * from t5;
+----+------+------+
| id | sex | name |
+----+------+------+
| 1 | xx | qq |
| 2 | xx | ww |
| 3 | yy | ee |
| 4 | xx | yy4 |
| 5 | yy | tt |
| 6 | yy | yy |
+----+------+------+
6 rows in set (0.00 sec)
PS:VALUES函式只在insert … on duplicate key update 語句中有意義,其他則返回NULL。
insert — on duplicate key update 執行原理
插入新行,判斷是否和已有記錄存在鍵值衝突,若有,則更新舊行為新行(先觸發before update 觸發器,更新後觸發after update)
replace into 語句,
在沒有鍵值衝突時,完全等價與insert into ,有鍵值衝突時,會將新行替換舊行
測試
MariaDB [test]> select * from t5;
+----+------+------+
| id | sex | name |
+----+------+------+
| 1 | xx | qq |
| 2 | xx | ww |
| 3 | yy | ee |
| 4 | xx | yy4 |
| 5 | yy | tt |
| 6 | yy | yy |
+----+------+------+
6 rows in set (0.00 sec)
MariaDB [test]> replace into t5 values(4,'yy','xx');
Query OK, 2 rows affected (0.00 sec)
MariaDB [test]> select * from t5;
+----+------+------+
| id | sex | name |
+----+------+------+
| 1 | xx | qq |
| 2 | xx | ww |
| 3 | yy | ee |
| 4 | yy | xx |
| 5 | yy | tt |
| 6 | yy | yy |
+----+------+------+
6 rows in set (0.00 sec)
replace into 執行原理
插入新行,判斷是否衝突(觸發before insert觸發器),若有,則刪除舊行,並插入新行(before delete —> after delete -> after insert)