两种选择:
- 一个使用
INSERT INTO ... SELECT 和LEFT OUTER JOIN;和
- 另一个使用
MERGE
SQL Fiddle
Oracle 11g R2 架构设置:
CREATE TABLE city (
ID NUMBER(2) PRIMARY KEY,
NAME VARCHAR2(20)
);
INSERT INTO city
SELECT 1, 'City Name' FROM DUAL;
CREATE TABLE city_errors (
ID NUMBER(2),
NAME VARCHAR2(20),
TS TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ERROR VARCHAR2(20)
);
查询 1:
DECLARE
city_id CITY.ID%TYPE := 2;
city_name CITY.NAME%TYPE := 'City Name';
namingError EXCEPTION;
PRAGMA EXCEPTION_INIT( namingError, -20001 );
BEGIN
INSERT INTO city ( id, name )
SELECT city_id,
city_name
FROM DUAL d
LEFT OUTER JOIN
city c
ON ( c.name = city_name )
WHERE c.id IS NULL;
IF SQL%ROWCOUNT = 0 THEN
RAISE namingError;
END IF;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
-- Do something when duplicate ID found.
INSERT INTO city_errors ( ID, NAME, ERROR ) VALUES ( city_id, city_name, 'Duplicate ID' );
WHEN namingError THEN
-- Do something when duplicate Name found.
INSERT INTO city_errors ( ID, NAME, ERROR ) VALUES ( city_id, city_name, 'Duplicate Name' );
END;
Results:
查询 2:
DECLARE
city_id CITY.ID%TYPE := 3;
city_name CITY.NAME%TYPE := 'City Name';
namingError EXCEPTION;
PRAGMA EXCEPTION_INIT( namingError, -20001 );
BEGIN
MERGE INTO city c
USING ( SELECT city_id AS id,
city_name AS name
FROM DUAL ) d
ON ( c.Name = d.Name )
WHEN NOT MATCHED THEN
INSERT VALUES ( d.id, d.name );
IF SQL%ROWCOUNT = 0 THEN
RAISE namingError;
END IF;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
-- Do something when duplicate ID found.
INSERT INTO city_errors ( ID, NAME, ERROR ) VALUES ( city_id, city_name, 'Duplicate ID' );
WHEN namingError THEN
-- Do something when duplicate Name found.
INSERT INTO city_errors ( ID, NAME, ERROR ) VALUES ( city_id, city_name, 'Duplicate Name' );
END;
Results:
查询 3:
SELECT * FROM City
Results:
| ID | NAME |
|----|-----------|
| 1 | City Name |
查询 4:
SELECT * FROM City_Errors
Results:
| ID | NAME | TS | ERROR |
|----|-----------|--------------------------------|----------------|
| 2 | City Name | January, 02 2014 20:01:49+0000 | Duplicate Name |
| 3 | City Name | January, 02 2014 20:01:49+0000 | Duplicate Name |