sql >> Base de Datos >  >> RDS >> Oracle

Cómo crear un activador de fila PL/SQL que valide una columna de otra tabla

Hay varios problemas con su gatillo. Comencemos con la 'relación' entre una declaración de selección y el código restante. En este caso particular, select.. y el if...end_if (por el momento, asuma que su selección realmente funciona, no lo hace, pero solo asuma). Ahora concéntrese en la cláusula WHERE.

SELECT SUPPLIER.TRUSTED_SUPPLIER
    INTO TRUST
    ...
    WHERE SUPPLIER.TRUSTED_SUPPLIER = 'YES';

IF TRUST = 'NO' THEN ...

Dado que su selección devuelve SOLO SÍ, la declaración if nunca será Verdadera. Por lo tanto, la excepción de la aplicación nunca se puede generar. Ahora, ¿cuáles son los problemas con select .
Bueno, primero está accediendo a la tabla sobre la que se dispara el gatillo. Mientras que en algunos casos puede salirse con la suya, pero generalmente resulta en un ORA -04091:la tabla está mutando, es posible que el disparador/función no la vea . Es un fracaso evitar siempre hacer referencia a la tabla de activación por completo. Usted hace referencia a los datos de la tabla con los pseudo registros :NEW y/o :OLD. En segundo lugar, su consulta no está haciendo lo que cree que es. Dice

Sin embargo, la cláusula INTO requiere que la declaración devuelva exactamente 1 fila . Más de 1 fila da como resultado la excepción, y 0 filas da como resultado un no data found excepción.
Finalmente, hay un problema con la declaración raise_application_error statement . Si se ejecutara, generaría un argumento numérico... está fuera de rango excepción. El primer parámetro debe estar entre -20999 y -20000 (número negativo). Entonces, ¿cómo se ve el resultado?

create or replace trigger verify_supplier_trust
before insert or update on product
for each row 
declare 
    trust varchar2(3);

begin
    select supplier.trusted_supplier
      into trust
      from supplier 
     where supplier.company_name = :new.supplier_name
       and supplier.trusted_supplier = 'YES';
exception
   when no_data_found then 
        raise_application_error(-20001, 'supplier not trusted');
end;
/

NOTAS:
No utilice el tipo de datos VARCHAR. Está permitido, pero Oracle lo desaconseja. Significa que se reservan el derecho de cambiar lo que hace en cualquier momento. Utilice el VARCHAR2 recomendado en su lugar.
Cambio el disparador para que se dispare en Insertar o Actualizar. Si se activa en Insertar, solo alguien PUEDE cambiar el nombre_del_proveedor para hacer referencia a un proveedor que no es de confianza y todo estaría bien.