在ORACLE中防止重复值INSERT

时间:2017-04-25 19:19:56

标签: sql oracle plsql merge

我的目标是通过在插入之前检查列中的现有值来防止插入重复数据。这与在MS SQL中使用'IF NOT EXISTS()...'的效果相同。

我无法在Oracle 11g中完成此任务。据我所知,Oracle PLSQL没有提供相同的语句。请纠正我的理解。

在我的研究中,我发现'MERGE'是实现这一目标的一种方式。

我的PLSQL在下面,但不起作用。查询结果为“0行合并”

EMP表的ID为IDENTITY COLUMN,如下表所示。

MERGE INTO EMP E
USING 
(SELECT ID, EMAIL FROM EMP WHERE EMAIL = 'test@email.com') T
ON (E.EMAIL = T.EMAIL)
WHEN NOT MATCHED THEN
INSERT  
(
  F_NAME
  , L_NAME 
  , EMAIL
)
VALUES
(
  'Employee'
  , 'Test'
  , 'ZZZZ@email.com'
);
COMMIT;

EMP表的表示在下面

"EMP" TABLE
    ID       F_NAME          L_NAME          EMAIL
    -------  ------------    ------------    ------------
    1        John            Smith           test@email.com

我尝试使用IF NOT EXISTS的尝试如下。 proc和query在MS SQL中运行良好,但在Oracle 11g中的IF语句之后产生语法错误:

CREATE OR REPLACE PROCEDURE "SPADDUPDATEEMP" 
(
  P_FNAME IN EMP.F_NAME%TYPE
  , P_LNAME IN EMP.L_NAME%TYPE
  , P_EMAIL IN EMP.EMAIL%TYPE
)
AS
IF NOT EXISTS (SELECT * FROM EMP WHERE EMAIL = P_EMAIL)
BEGIN
INSERT INTO EMP
(
  F_NAME
  , L_NAME
  , EMAIL
)
VALUES
(
  P_FNAME
  , P_LNAME
  , P_EMAIL
)
END;
COMMIT;

3 个答案:

答案 0 :(得分:3)

也许是这样的?

ALTER TABLE EMP ADD CONSTRAINT NO_DUPLICATE UNIQUE(ID,F_NAME,L_NAME,EMAIL);

Source

答案 1 :(得分:2)

使用:

INSERT INTO emp(
  F_NAME
  , L_NAME 
  , EMAIL
)
SELECT 
    'Employee'
  , 'Test'
  , 'ZZZZ@email.com'
FROM dual
WHERE NOT EXISTS (
   SELECT 1 FROM emp WHERE EMAIL = 'ZZZZ@email.com'
);

答案 2 :(得分:1)

如果您想要像标记的答案那样做,但是使用合并声明,您应该以这种方式重写查询:

MERGE INTO EMP E
USING 
(SELECT 'Employee'       AS F_NAME
       ,'Test'           AS L_NAME
       ,'ZZZZ@email.com' AS EMAIL 
   FROM dual ) T
ON (E.EMAIL = T.EMAIL)
WHEN NOT MATCHED THEN
INSERT  
(
   F_NAME
  ,L_NAME 
  ,EMAIL
)
VALUES
(
   T.F_NAME
  ,T.L_NAME
  ,T.EMAIL
);