【问题标题】:Procedure to insert data if not exist pl sql如果不存在则插入数据的过程pl sql
【发布时间】:2020-12-04 10:49:34
【问题描述】:

我有一个包含这些列(id、first_name、birth)的表。我想创建一个仅在表中不存在插入的 id 时才插入新客户的过程。如果它已经存在,则不要插入它。到目前为止,这是我的代码,但出现错误“忽略第 3 行 sql 语句”。任何的想法?我需要在 oracle 中使用过程和 pl sql。谢谢!

CREATE OR REPLACE PROCEDURE add_emp(v_id   IN int,
                                    v_name IN varchar2,
                                    v_bday IN date) IS
BEGIN
  INSERT INTO Employees
    (Id, First_name, Birth)
    SELECT *
      FROM (SELECT v_id, v_name, v_bday) AS tmp
     WHERE NOT EXISTS (SELECT Id FROM Employees WHERE Id = v_id);
END;
/

DECLARE
  m_id   int := 3;
  m_name varchar2 := 'John';
  m_bday date := '16-Dec-1990';
BEGIN
  add_cust(m_id, m_name, m_bday);
END;
/

【问题讨论】:

  • 如果 ID 是一个 PK,或者至少是 UNIQUE,那么您不需要先检查它(“如果已经存在,则不要插入它”)。只做插入。如果 ID 已经存在,它将抛出一个异常,您可以根据需要处理该异常。

标签: sql oracle plsql sql-insert


【解决方案1】:

您的程序存在一些语法问题,已在以下代码中修复:

CREATE OR REPLACE PROCEDURE ADD_EMP (
    V_ID     IN   INT,
    V_NAME   IN   VARCHAR2,
    V_BDAY   IN   DATE
) IS
BEGIN
    INSERT INTO EMPLOYEES (
        ID,
        FIRST_NAME,
        BIRTH
    )
        SELECT V_ID,
               V_NAME,
               V_BDAY
          FROM DUAL -- FROM clause was missing
         WHERE NOT EXISTS (
            SELECT ID
              FROM EMPLOYEES
             WHERE ID = V_ID
        );

END;
/

此外,您的调用 PL/SQL 块存在一些问题,这些问题已在以下代码中得到纠正:

DECLARE
    M_ID     INT := 3;
    M_NAME   VARCHAR2(10) := 'John'; -- varchar2 must be declared with size
    M_BDAY   DATE := DATE '1990-12-16'; -- added date literal to convert string to date
BEGIN
    ADD_CUST(M_ID, M_NAME, M_BDAY);
END;
/

【讨论】:

    【解决方案2】:

    在没有 FROM 子句的情况下,Oracle SELECT 不起作用(其他 DBMS 产品不同)。所以你需要提供一张桌子;你可以使用 DUAL,它是 Oracle 提供的一个虚拟表,保证返回一行。

    INSERT INTO Employees(Id,First_name,Birth)
    SELECT v_id, v_name, v_bday 
    from dual
    WHERE NOT EXISTS (
        SELECT Id FROM Employees WHERE Id = v_id
    );
    

    【讨论】:

      【解决方案3】:

      您的 INSERT 语句只需稍作改动即可工作

      CREATE OR REPLACE PROCEDURE add_emp(v_id   Employees.Id%type,
                                          v_name Employees.First_name%type,
                                          v_bday Employees.Birth%type) IS
      BEGIN
        INSERT INTO Employees
          (Id, First_name, Birth)
          SELECT v_id, v_name, v_bday
            FROM dual
           WHERE NOT EXISTS (SELECT * FROM Employees WHERE Id = v_id);
      END;
      /
      

      您可以将 INSERT 语句替换为 MERGE 作为替代 DML,例如

      MERGE INTO Employees e1
      USING 
      (SELECT v_id AS id, v_name AS First_name, v_bday AS birth
            FROM dual) e2
         ON ( e1.id = e2.id )
       WHEN MATCHED THEN UPDATE SET e1.First_name = e2.First_name,
                                    e1.Birth = e2.Birth -- If you need to change for the matching case
       WHEN NOT MATCHED THEN INSERT( e1.id, e1.First_name, e1.birth ) 
                             VALUES( e2.id, e2.First_name, e2.birth );
      

      【讨论】:

        猜你喜欢
        • 2018-09-17
        • 2017-04-24
        • 1970-01-01
        • 2015-03-02
        • 2013-11-13
        • 1970-01-01
        • 2021-02-19
        • 1970-01-01
        • 2013-11-15
        相关资源
        最近更新 更多