【问题标题】:How to replace SELECT statement inside IF statement for it to work [duplicate]如何在 IF 语句中替换 SELECT 语句以使其正常工作[重复]
【发布时间】:2014-01-20 01:37:05
【问题描述】:

我有一个简单的问题 - 举个例子,让我们来看看表格

城市(ID,姓名)。

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

代码示例是:

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

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

【问题讨论】:

  • 这是不同的问题,伙计。其他主题非常好,但是当城市存在时我需要一个选项来首先检查并引发错误,我在其他主题中找不到我的问题的答案:(
  • 您的桌子上是否有任何唯一(自然)键?让数据库为您完成工作总是更好。如果您不这样做,那么您真的需要引发错误吗?如果有人试图创造已经存在的东西,这有关系吗?
  • 这是我大学的任务,在它的描述中,ID 字段只有唯一键,我应该自己处理命名错误。

标签: database oracle select plsql


【解决方案1】:
 IF NOT EXISTS(SELECT 1 FROM CITY WHERE NAME = <CITYNAME>) 
    INSERT INTO City(ID, NAME) VALUES(100, cityName);

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

我阅读了第二个查询here

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

【讨论】:

  • 第一个语句无效;你不能在 SQL 之外使用exists。第二个语句可以工作(没有引号 cityName 因为它是一个 PL/SQL 变量);但要满足异常要求,您需要测试 if sql%rowcount = 0 并引发异常,因为这表明没有插入新行,因为名称已经存在。
【解决方案2】:

您可以使用合并命令来执行插入到表中。虽然合并命令用于在数据不存在时执行插入,或者在这种情况下数据存在时执行更新,因为您只有两个字段,它只会为您执行插入。

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

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

【讨论】:

  • 希望我有足够的声誉来支持它,因为它不能回答我的问题,但它是非常有趣且有用的东西。
  • @Roff 很高兴你发现它至少有用!
【解决方案3】:

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

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;

分享和享受。

【讨论】:

  • 嘿,这正是我所做的,但无法为我自己的问题添加答案。它工作得很好,感谢您的贡献。
【解决方案4】:

两种选择:

  • 一个使用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 |

【讨论】:

  • 哇,这比我做的要复杂得多,我想我会坚持使用@BobJarvis 的答案,但无论如何这是非常好的事情,我会在未来使用它。非常感谢,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 2013-06-12
  • 2020-09-04
  • 1970-01-01
相关资源
最近更新 更多