數據庫中更新或插入表記錄

會碰到下列場景:當記錄,在目標表中存在就更新值,若不存在就插入記錄。mysql

1、示例數據

-- test_source 數據源表

CREATE TABLE `test_source` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `BWKEY` varchar(255) DEFAULT NULL,
  `MATNR` varchar(255) DEFAULT NULL,
  `VERPR` double(255,0) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `sBWKEY` (`BWKEY`,`MATNR`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8

INSERT INTO `zjkywms`.`test_source`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (1, '2105', 'A', 1);
INSERT INTO `zjkywms`.`test_source`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (2, '2105', 'B', 2);
INSERT INTO `zjkywms`.`test_source`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (3, '2105', 'C', 3);
INSERT INTO `zjkywms`.`test_source`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (4, '2106', 'A', 4);
INSERT INTO `zjkywms`.`test_source`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (5, '2106', 'B', 5);
INSERT INTO `zjkywms`.`test_source`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (6, '2106', 'C', 6);

-- test_target 目標表/待更新或插入

CREATE TABLE `test_target` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `BWKEY` varchar(255) DEFAULT NULL,
  `MATNR` varchar(255) DEFAULT NULL,
  `VERPR` double(255,0) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `tBWKEY` (`BWKEY`,`MATNR`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (1, '2105', 'A', 7);
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (2, '2106', 'C', 6);
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (3, '2107', 'Z', 9);

2、update + insert 二步操做

-- 待更新的記錄
SELECT * from test_target t inner JOIN test_source s on s.BWKEY=t.BWKEY and s.MATNR=t.MATNR;
-- update test_target t inner JOIN test_source s on s.BWKEY=t.BWKEY and s.MATNR=t.MATNR set t.VERPR=s.VERPR

-- 待插入的記錄
-- insert into test_target (BWKEY,MATNR,VERPR)
 SELECT s.BWKEY,s.MATNR,s.VERPR from test_source s where not exists (select 1 from test_target t where s.BWKEY=t.BWKEY and s.MATNR=t.MATNR);

效果

mysql> select * from test_target;
+----+-------+-------+-------+
| id | BWKEY | MATNR | VERPR |
+----+-------+-------+-------+
|  1 | 2105  | A     |     1 |
|  2 | 2106  | C     |     6 |
|  5 | 2107  | Z     |     9 |
|  6 | 2105  | B     |     2 |
|  7 | 2105  | C     |     3 |
|  8 | 2106  | A     |     4 |
|  9 | 2106  | B     |     5 |
+----+-------+-------+-------+
7 rows in set (0.03 sec)

記錄ID:1是更新記錄,原值是7;6~9是插入記錄。sql

 

3、Oracle一步操做

-- merge into應用:實現 無則insert插入,有則update更新,一條語句直接進行insert/update操做
MERGE INTO table1 alias1
          USING (table2
|view2|sub_query2) alias2
         
ON (join condition)
     
WHEN MATCHED THEN
          UPDATE table1
           
SET col1 = col_val1,
                col2
= col2_val2
           
[where ]
      WHEN NOT MATCHED THEN
                INSERT (column_list) VALUES (column_values)
                
[where ];

4、MySQL一步操做

方案1: insert into table (key) values (value) ON DUPLICATE KEY UPDATE key = value

    > 該方案要求有一個惟一索引,當插入的時候先判斷,若是該字段存在數據,則更新該條數據,若是不存在則插入
    > 注意:當您使用 ON DUPLICATE KEY UPDATE 時,DELAYED選項被忽略(DELAYED 作爲快速插入,並非很關心時效性,提升插入性能)。性能

truncate test_target;
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (1, '2105', 'A', 7);
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (2, '2106', 'C', 6);
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (3, '2107', 'Z', 9);
select * from test_target;

insert into test_target (`BWKEY`, `MATNR`, `VERPR`) values ('2105', 'A', 1) ON DUPLICATE KEY UPDATE VERPR = VALUES(VERPR);
insert into test_target (`BWKEY`, `MATNR`, `VERPR`) values ('2106', 'X', 99) ON DUPLICATE KEY UPDATE VERPR = VALUES(VERPR);

效果

mysql> select * from test_target;
+----+-------+-------+-------+
| id | BWKEY | MATNR | VERPR |
+----+-------+-------+-------+
|  1 | 2105  | A     |     1 |
|  2 | 2106  | C     |     6 |
|  3 | 2107  | Z     |     9 |
|  5 | 2106  | X     |    99 |
+----+-------+-------+-------+
4 rows in set (0.03 sec)

記錄ID:1是更新記錄,原值是7;5是插入記錄。spa

truncate test_target;
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (1, '2105', 'A', 7);
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (2, '2106', 'C', 6);
INSERT INTO `zjkywms`.`test_target`(`id`, `BWKEY`, `MATNR`, `VERPR`) VALUES (3, '2107', 'Z', 9);
select * from test_target;
insert into test_target (`BWKEY`, `MATNR`, `VERPR`) select `BWKEY`, `MATNR`, `VERPR` from test_source ON DUPLICATE KEY UPDATE VERPR = VALUES(VERPR);

效果

mysql> select * from test_target;
+----+-------+-------+-------+
| id | BWKEY | MATNR | VERPR |
+----+-------+-------+-------+
|  1 | 2105  | A     |     1 |
|  2 | 2106  | C     |     6 |
|  3 | 2107  | Z     |     9 |
|  4 | 2105  | B     |     2 |
|  5 | 2105  | C     |     3 |
|  6 | 2106  | A     |     4 |
|  7 | 2106  | B     |     5 |
+----+-------+-------+-------+
7 rows in set (0.04 sec)

記錄ID:1是更新記錄,原值是7;4~7是插入記錄。code

 

方案2: replace into table (key) values (value)

    > 1.嘗試把新行插入到表中
    > 2. 當由於對於主鍵或惟一關鍵字出現重複關鍵字錯誤而形成插入失敗時:
        > a. 從表中刪除含有重複關鍵字值的衝突行
        > b. 再次嘗試把新行插入到表中
    > 該方案會將以前的數據刪除,而後從新插入新的數據.若是新的數據某個字段是空的,執行完replace into以後,該字段會變成字段的默認值blog

相關文章
相關標籤/搜索