SQL server
在向表中插入數(shù)據(jù)的時(shí)候谜诫,經(jīng)常遇到這樣的情況:
- 首先判斷數(shù)據(jù)是否存在缰揪;
- 如果不存在竹握,則插入:
3.如果存在,則更新沮协。
if not exists (select 1 from t where id = 1)
insert into t(id, update_time) values(1, getdate())
else
update t set update_time = getdate() where id = 1
或者
if exists (select 1 from t where id = 1)
insert into t(id, update_time) values(1, getdate())
else
update t set update_time = getdate() where id = 1
mysql
replace into 跟 insert 功能類似龄捡,不同點(diǎn)在于:replace into 首先嘗試插入數(shù)據(jù)到表中,
- 如果發(fā)現(xiàn)表中已經(jīng)有此行數(shù)據(jù)(根據(jù)主鍵或者唯一索引判斷)則先刪除此行數(shù)據(jù)慷暂,然后插入新的數(shù)據(jù)聘殖。
- 否則,直接插入新數(shù)據(jù)。
要注意的是:插入數(shù)據(jù)的表必須有主鍵或者是唯一索引奸腺!否則的話餐禁,replace into 會(huì)直接插入數(shù)據(jù),這將導(dǎo)致表中出現(xiàn)重復(fù)的數(shù)據(jù)突照。
replace into
###插入或替換
REPLACE INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99);
若id=1的記錄不存在帮非,REPLACE語句將插入新記錄,否則讹蘑,當(dāng)前id=1的記錄將被刪除末盔,然后再插入新記錄。
###插入或更新
INSERT INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99) ON DUPLICATE KEY UPDATE name='小明', gender='F', score=99;
###插入或忽略
INSERT IGNORE INTO students (id, class_id, name, gender, score) VALUES (1, 1, '小明', 'F', 99);
oracle
declare num number;
begin
select count(1) into num from user_tables where table_name='ACCOUNT';
if num > 0 then
dbms_output.put_line('存在!');
execute immediate 'drop table ACCOUNT ';
end if;
execute immediate 'create table Account
(
AccountID nvarchar2(50) primary key,
AccountName nvarchar2(50)
)';
dbms_output.put_line('成功創(chuàng)建表!');
end;
1:隱式游標(biāo)法 SQL%NOTFOUND SQL%FOUND
SQL%NOTFOUND 是SQL中的一個(gè)隱式游標(biāo)衔肢,在增刪查改的時(shí)候自動(dòng)打開庄岖,如果有至少有一條記錄受影響,都會(huì)返回false角骤,這就就巧妙的構(gòu)思出了第一種解決方案:
begin
update account set AccountName = '修改-a' where AccountID = '5';
IF SQL%NOTFOUND THEN
insert into account(AccountID,AccountName) values('5','添加-b');
END IF;
end;
先根據(jù)唯一ID到數(shù)據(jù)表中修改一條記錄隅忿,如果這條記錄在表中存在,則修改邦尊,并且SQL%NOTFOUND返回false背桐。如果修改的記錄不存在,SQL%NOTFOUND返回true蝉揍,并且執(zhí)行插入語句链峭。
2:異常法 DUP_VAL_ON_INDEX
當(dāng)Oracle語句執(zhí)行時(shí),發(fā)生了異常exception進(jìn)行處理
begin
insert into account(AccountID,AccountName) values('6','添加-b');
exception
when DUP_VAL_ON_INDEX then
begin
update account set AccountName = '修改-b' where AccountID = '6';
end;
end;
當(dāng)往表中插入一條數(shù)據(jù)又沾,因?yàn)楸碇杏兄麈I約束弊仪,如果插入的數(shù)據(jù)在表中已經(jīng)存在,則會(huì)拋出異常杖刷,在異常拋出后進(jìn)行修改励饵。
3:虛擬表法 dual:
dual是一個(gè)虛擬表,用來構(gòu)成select的語法規(guī)則滑燃,oracle保證dual里面永遠(yuǎn)只有一條記錄役听。
declare t_count number;
begin
select count(*) into t_count from dual where exists(select 1 from account where AccountID='11');
if t_count< 1 then
dbms_output.put_line('添加');
insert into account(AccountID,AccountName) values('11','添加-11');
else
dbms_output.put_line('修改');
update account set AccountName = '修改-11' where AccountID = '11';
end if;
end;
先聲明一個(gè)變量t_count,表dual表的值賦給t_count,如果這個(gè)值小于1表窘,表示記錄不存在典予,進(jìn)行插入操作,反之乐严,存在就進(jìn)行修改操作瘤袖。
4:no_data_found法
先查找要插入的記錄是否存在,存在則修改昂验,不存在則插入捂敌。具體的實(shí)現(xiàn)如下:
declare t_cols number;
begin
select AccountName into t_cols from account where AccountID = '8';
exception
when no_data_found then begin
--dbms_output.put_line('添加');
insert into account(AccountID,AccountName) values('8','添加-8');
end;
when others then
begin
--dbms_output.put_line('修改');
update account set AccountName = '修改-8' where AccountID = '8';
end;
end;
5:merge法
先來看一下merge的語法昭娩,
MERGE INTO table_name alias1
USING (table|view|sub_query) alias2
ON (join condition)
WHEN MATCHED THEN
UPDATE table_name SET col1 = col_val1
WHEN NOT MATCHED THEN
INSERT (column_list) VALUES (column_values);
模仿
merge into Account t1
using (select '3' AccountID,'肖文博' AccountName from dual) t2
on (t1.AccountID = t2.AccountID)
when matched then
update set t1.AccountName = t2.AccountName
when not matched then
insert values (t2.AccountID, t2.AccountName);
commit;