将唯一值插入到表中的过程不起作用

问题描述

我是这门语言的初学者,我被要求通过程序将一些独特的变量插入到表 aeropuerto 和终端中(与表中的其余变量相比,这些变量必须是唯一的),经过思考,这就我来了。您对如何编辑代码或如何使用简单的说明插入有任何建议吗? (我们还没有在课程中走那么远:))

create or replace PROCEDURE EX3 (
    IDAE IN NUMBER,NOMA IN VARCHAR2,PLAC IN VARCHAR2,IDTER IN NUMBER,NUMT IN NUMBER)
AS 
BEGIN
  
    IF IDAE!=AEROPUERTO.ID AND NOMA!=AEROPUERTO.NOMBRE AND PLAC!=AEROPUERTO.LUGAR THEN
            INSERT INTO AEROPUERTO(ID,NOMBRE,LUGAR) 
            VALUES (ID_AAUX,NOMA,PLAC);
    END IF;
    IF IDTER!=TERMINAL.ID AND NUMT!=TERMINAL.NUMERO AND IDAE!=TERMINAL.ID_AEROPUERTO THEN
            INSERT INTO TERMINAL(ID,NUMERO,ID_AEROPUERTO) 
            VALUES (ID_TAUX,NUMT,IDAE);
    END IF;
END EX3;

解决方法

最简单的方法可能是在您的 NOT EXISTS 语句中使用 INSERT 子句。

create or replace PROCEDURE EX3 (
  IDAE IN NUMBER,NOMA IN VARCHAR2,PLAC IN VARCHAR2,IDTER IN NUMBER,NUMT IN NUMBER )
AS 
BEGIN
  INSERT INTO AEROPUERTO(ID,NOMBRE,LUGAR) 
    SELECT idae,noma,plac
      FROM dual
     WHERE NOT EXISTS( SELECT 1
                         FROM AEROPUERTO a
                        WHERE a.id = idae
                          AND a.nombre = noma
                          AND a.lugar = plac );

  INSERT INTO TERMINAL(ID,NUMERO,ID_AEROPUERTO) 
    SELECT idter,numt,idae
      FROM dual
     WHERE NOT EXISTS( SELECT 1
                         FROM terminal t
                        WHERE t.id = idter
                          AND t.numero = numt
                          AND t.id_aeropuerto = idae );
END EX3;

然而,根据实际获得重复值的常见程度,并假设存在唯一约束,那么尝试 insert 并捕获异常可能更有效

create or replace PROCEDURE EX3 (
  IDAE IN NUMBER,NUMT IN NUMBER )
AS 
BEGIN
  BEGIN
    INSERT INTO AEROPUERTO(ID,LUGAR) 
      VALUES( idae,plac );
  EXCEPTION
    WHEN dup_val_on_index
    THEN
      null;  -- Ignore the error if the row already exists
  END;

  BEGIN
    INSERT INTO TERMINAL(ID,ID_AEROPUERTO) 
      VALUES( idter,idae );
  EXCEPTION
    WHEN dup_val_on_index
    THEN
      null;  -- Ignore the error if the row already exists
  END;
END EX3;

顺便说一句,如果您使用参数和局部变量的命名约定,确保清楚它们引用的是哪一列,但不会与实际列的名称冲突,您的生活通常会更轻松。如果您使用锚定类型使特定参数应该与哪些列匹配,那么您的生活会更轻松。

如果您的程序已声明

create or replace PROCEDURE EX3 (
  p_id_aeropuerto IN aeropuerto.id%type,p_nombre        IN aeropuerto.nombre%type,p_lugar         IN aeropuerto.lugar%type,p_id_terminal   IN terminal.id%type,p_numero        IN terminal.numero%type )

它可能更容易阅读,并且更清楚哪些参数映射到哪个表。这也意味着更少的维护,因为当有人决定他们需要增加列的长度时,您不必调整您的 PL/SQL 代码(假设您总是使用锚定类型)。

我还倾向于建议在 id_aeropuertoid_terminal 表的定义中使用 aeropuertoterminal,而不是在每个表中使用通用的 id 列桌子。这更多是风格问题,但我总是发现更容易阅读代码,其中您加入相同的列名,并且具有相同名称的列意味着相同的事情。在一堆表中具有相同的 id 列,每个表都表示不同的含义,这让我花更多时间查看代码以确保它没有加入错误的标识符。