Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 如何替换IF语句中的SELECT语句以使其正常工作_Database_Oracle_Select_Plsql - Fatal编程技术网

Database 如何替换IF语句中的SELECT语句以使其正常工作

Database 如何替换IF语句中的SELECT语句以使其正常工作,database,oracle,select,plsql,Database,Oracle,Select,Plsql,我有一个简单的问题-为了举例,让我们坐在桌子上 城市(ID、姓名) 一个想法是,当我想添加新城市时,我首先要确保它不在表城市中 代码示例为: IF cityName NOT IN (SELECT name FROM city) THEN INSERT INTO City(ID, NAME) VALUES(100, cityName); ELSE Raise namingError; END IF; 然而,我不能在if语句中包含该子查询,那么我应该用什么替换

我有一个简单的问题-为了举例,让我们坐在桌子上

城市(ID、姓名)

一个想法是,当我想添加新城市时,我首先要确保它不在表城市中

代码示例为:

IF cityName NOT IN (SELECT name FROM city) THEN   
  INSERT INTO City(ID, NAME) VALUES(100, cityName); 
ELSE        
  Raise namingError;   
END IF;
然而,我不能在if语句中包含该子查询,那么我应该用什么替换它呢?我可以使用什么样的列表、变量或技巧

 IF NOT EXISTS(SELECT 1 FROM CITY WHERE NAME = <CITYNAME>) 
    INSERT INTO City(ID, NAME) VALUES(100, cityName);
我读了第二个问题

我没有一个数据库来尝试这一点,但这应该是可行的

我读了第二个问题


我没有一个数据库来尝试这一点,但这应该可以工作

您可以使用merge命令来执行对表的插入。当merge命令用于在数据不存在时执行插入,或在数据存在时执行更新时,在这种情况下,由于您只有两个字段,因此它将为您执行插入

如果您想从一个或多个表中获取数据并将它们合并到一个表中,这将非常有用

MERGE INTO city c
    USING (SELECT * FROM city_import ) h
    ON (c.id = h.id and c.city = h.city)
  WHEN MATCHED THEN

  WHEN NOT MATCHED THEN
    INSERT (id, city)
    VALUES (h.id, h.city);

您可以使用merge命令执行表中的插入操作。当merge命令用于在数据不存在时执行插入,或在数据存在时执行更新时,在这种情况下,由于您只有两个字段,因此它将为您执行插入

如果您想从一个或多个表中获取数据并将它们合并到一个表中,这将非常有用

MERGE INTO city c
    USING (SELECT * FROM city_import ) h
    ON (c.id = h.id and c.city = h.city)
  WHEN MATCHED THEN

  WHEN NOT MATCHED THEN
    INSERT (id, city)
    VALUES (h.id, h.city);

如果是我,我可能会做类似的事情

DECLARE
  rowCity  CITY%ROWTYPE;
BEGIN
  SELECT * INTO rowCity FROM CITY c WHERE c.NAME = cityName;

  -- If we get here it means the city already exists; thus, we raise an exception

  RAISE namingError;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    -- cityName not found in CITY; therefore we insert the necessary row
    INSERT INTO City(ID, NAME) VALUES(100, cityName);
END;

分享和享受。

如果是我,我可能会做类似的事情

DECLARE
  rowCity  CITY%ROWTYPE;
BEGIN
  SELECT * INTO rowCity FROM CITY c WHERE c.NAME = cityName;

  -- If we get here it means the city already exists; thus, we raise an exception

  RAISE namingError;
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    -- cityName not found in CITY; therefore we insert the necessary row
    INSERT INTO City(ID, NAME) VALUES(100, cityName);
END;
分享和享受。

两种选择:

  • 一个使用
    插入到。。。选择带有
    左外连接的
    ;及
  • 另一个使用
    MERGE

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询1

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询2

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询3

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询4

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
两种选择:

  • 一个使用
    插入到。。。选择带有
    左外连接的
    ;及
  • 另一个使用
    MERGE

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询1

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询2

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询3

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |
查询4

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

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)
);
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;
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;
SELECT * FROM City
| ID |      NAME |
|----|-----------|
|  1 | City Name |
SELECT * FROM City_Errors
| 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 |

这是不同的问题,伙计。另一个主题很好,但我需要一个选项,当城市存在时,首先检查并提出错误,我在另一个主题中找不到我问题的答案:(你有什么独特的(自然的)吗表上的键?让DB为你做这项工作总是更好的。如果你不这样做,那么你真的需要提出错误吗?如果有人试图创建已经存在的东西有关系吗?这是我的大学的任务,这在它的描述中,ID字段上只有唯一的键,我应该通过m来处理命名错误你自己。这是不同的问题,伙计。另一个主题很好,但我需要一个选项,当城市存在时,首先检查并提出错误,我无法在另一个主题中找到我问题的答案:(你有什么独特的(自然的)吗)表上的键?让DB为你做这项工作总是更好的。如果你不这样做,那么你真的需要提出错误吗?如果有人试图创建已经存在的东西有关系吗?这是我的大学的任务,这在它的描述中,ID字段上只有唯一的键,我应该通过m来处理命名错误你自己。希望我有足够的声誉来提高这一点,因为它不是我问题的答案,但它是非常有趣的东西,它是有用的。@Roff很高兴你发现它至少有用!希望我有足够的声誉来提高这一点,因为它不是我问题的答案,但它是非常有趣的东西,它是有用的。@Roff很高兴你发现它至少有用!呵呵,是的at正是我所做的,但无法为我自己的问题添加答案。它工作得很好,感谢您的贡献。呵呵,是的,这正是我所做的,但无法为我自己的问题添加答案。它工作得很好,感谢您的贡献。第一条语句无效;您不能在SQL之外使用
exists
。第二条语句将有效k(由于它是PL/SQL变量,所以在
cityName
周围没有引号);但要满足异常要求,您需要在sql%rowcount=0时测试
,如果是,则引发异常,因为这表明没有插入新行,因为名称已经存在。第一条语句无效;不能在sql外部使用
exists
。第二条语句可以工作(由于它是PL/SQL变量,因此在
cityName
周围没有引号);但为了满足异常要求,如果sql%rowcount=0,您需要测试
,如果是,则引发异常,因为这将表明没有插入新行,因为名称已经存在。哇,这比我做的要复杂得多,我想我会坚持使用@BobJarvis answer,但无论如何,知道这一点很好,而且我我会在将来使用它。非常感谢,谢谢。哇,这比我做的要复杂得多,我想我会坚持使用@BobJarvis答案,但无论如何,知道它是一件非常好的事情,我会在将来使用它。非常感谢,谢谢。