TAG:
看见这个标题的人可能会嘲笑我,检查记录是否存在不是很简单吗:SELECT count(1) FROM tab WHERE id=key;当然,这样肯定是可以的。但是,如何结合业务,写出更高效更简洁的代码呢? 情况一:将存在于A表但不存在于B表的数据插入到B表,将存在于A表也存在于B表的数据更新到B表,可以这样写:
UPDATE B SET b.field=(select field FROM a WHERE a.id=b.id)
WHERE EXISTS(SELECT 1 FROM a WHERE a.id=b.id);
INSERT INTO B
SELECT a.id, a.field
FROM a
WHERE NOT EXISTS(SELECT 1 FROM b WHERE b.id=a.id);
COMMIT;
--这个例子通过exists来判断记录是否存在,主要用于两个集合(表)的操作 情况二:插入一条记录到A,如果A中已经有这条记录,则更新记录。
--(我们反过来写,先更新,再插入) UPDATE A SET field=value WHERE id=key;
IF SQL%NOTFOUND THEN --当一条记录都没更新的时候,SQL%NOTFOUND这个游标变量会为TRUE
INSERT INTO a VALUES(key, value);
END IF;
COMMIT;
--通过使用SQL%NOTFOUND这个游标变量,比起先SELECT COUNT(1)对应的记录,肯定更快 情况三:插入一条记录到A,如果记录已经存在,就放弃
--前提条件是:表存在唯一索引(或主键) BEGIN
INSERT INTO a VALUES(key, value);
COMMIT;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN --当发生主键冲突的时候,会产生DUP_VAL_ON_INDEX 的异常
ROLLBACK;
RETURN;
END;
--这里使用异常来代替去查询记录是否存在,既然发生了唯一索引冲突,则记录一定是存在的。 情况四:如果A表记录不存在,则我们做一些与A表无关的操作 DECLARE v_temp number(10); BEGIN SELECT 1 INTO v_temp FROM A WHERE id=key AND rownum<=1; EXCEPTION WHEN NO_DATA_FOUND THEN --do something END; --使用select into语句如果没有找到记录,会引发NO_DATA_FOUND的异常。
--注意:如果ID不是唯一的,要加上rownum<=1
--这种方法比起select count(1)来,只用检查到第一条存在的记录即可,速度很快。 (ah__fu) |