如何替换IF语句中的SELECT语句使其工作

时间:2014-01-02 15:05:34

标签: database oracle select plsql

我有一个简单的问题 - 例如,让我们有表

  

CITY(ID,姓名)。

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

代码示例如下:

IF cityName NOT IN (SELECT name FROM city) THEN   
  INSERT INTO City(ID, NAME) VALUES(100, cityName); 
ELSE        
  Raise namingError;   
END IF;

但是我不能在if语句中包含那个子查询,那么我应该用它替换它?我可以使用的任何类型的列表或变量或技巧?

4 个答案:

答案 0 :(得分:2)

 IF NOT EXISTS(SELECT 1 FROM CITY WHERE NAME = <CITYNAME>) 
    INSERT INTO City(ID, NAME) VALUES(100, cityName);

OR

 INSERT INTO City
  SELECT 100,'cityName'
   FROM dual 
         WHERE NOT EXISTS (SELECT 1
                 FROM CITY
                WHERE name = cityname
              )

我读了第二个查询here

我没有数据库来试试这个,但这应该可行

答案 1 :(得分:2)

您可以使用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);

http://www.oracle-base.com/articles/9i/merge-statement.php

答案 2 :(得分:1)

如果是我,我可能会做类似

的事情
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;

分享并享受。

答案 3 :(得分:0)

两个选项:

  • 使用INSERT INTO ... SELECTLEFT 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 |