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


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

一、示例數據

-- 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);

二、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是插入記錄。

 

三、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 ];

四、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是插入記錄。

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是插入記錄。

 

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

    > 1.嘗試把新行插入到表中
    > 2. 當因為對於主鍵或唯一關鍵字出現重復關鍵字錯誤而造成插入失敗時:
        > a. 從表中刪除含有重復關鍵字值的沖突行
        > b. 再次嘗試把新行插入到表中
    > 該方案會將之前的數據刪除,然后重新插入新的數據.如果新的數據某個字段是空的,執行完replace into之后,該字段會變成字段的默認值


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM