Link to home
Start Free TrialLog in
Avatar of pboix
pboix

asked on

DB2 Update trigger

I want to create a update trigger. Two tables are involved. The first is supplier and it has a column reliable that can be either 0 or 1. And the other one is the article table that has the columns
idSupplier, critical (0/1) and initialStatus (OK or QP quality pending).
The trigger I want to do is after updating the reliable column of suppliers if it is 0 update the articles of this supplier to initialStatus ='QP'. If it is 1 (reliable supplier) if the article is a critical one initial status must be set to QP and if not to OK.
I tried to write the trigger but I get sintax errors .





CONNECT TO FALCA;
CREATE TRIGGER DB2INST1.UPDTsupplier
AFTER  UPDATE OF reliable
ON RUMBO.TBLsupliers  
REFERENCING  OLD AS o  
NEW AS n  
FOR EACH ROW  MODE DB2SQL
WHEN ( o.reliable<>n.reliable)
BEGIN ATOMIC
if ( o.reliable=0 )  then
UPDATE RUMBO.TBLarticles ART
   SET initialstatus = 'QP'
   WHERE ART.idsupplier = n.idsupplier
else
UPDATE RUMBO.TBLarticles ART
   SET initialstatus= 'QP'
   WHERE ART.idsupplier = n.idsupplier
      and art.critical=0 ;
UPDATE RUMBO.TBLarticles ART
   SET initialstatus= 'OK'
   WHERE ART.idproveedor = n.idproveedor
      and art.critical=1
END^
CONNECT RESET^
Avatar of cubixSoftware
cubixSoftware

Sorry if this is a bit obvious, but is "AFTER  UPDATE OF reliable ON RUMBO.TBLsupliers" correct or should it be "AFTER  UPDATE OF reliable ON RUMBO.TBLsuppliers " ?

;)
You are missing soem semicolons.
one befor ethe ELSE, the other before the END.
Also teh IF construct needs to be concluded with END IF;

So
BEGIN ATOMIC

IF
<stmt>; [<stmt> ;]
ELSE
<stmt>; [<stmt>;]
END IF;
END

Cheers
Serge
CONNECT TO FALCA%
CREATE TRIGGER DB2INST1.UPDTsupplier AFTER
UPDATE OF reliable
ON RUMBO.TBLsupliers
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
MODE DB2SQL
BEGIN
      IF ( o.reliable <> n.reliable) THEN
            IF ( o.reliable = 0 ) THEN
                  UPDATE RUMBO.TBLarticles ART SET initialstatus = 'QP' WHERE   ART.idsupplier    = n.idsupplier
            ELSE
                  UPDATE RUMBO.TBLarticles ART SET initialstatus= 'QP' WHERE   ART.idsupplier   = n.idsupplier and art.critical = 0 ;
                  UPDATE RUMBO.TBLarticles ART SET initialstatus= 'OK' WHERE   ART.idproveedor  = n.idproveedor and art.critical = 1;
            END IF;
      END IF;
END%
CONNECT RESET%

Avatar of pboix

ASKER

Hi, the original sql sentence was written in spanish but I translated the table and columns name to be more easy to understand, so there are some little syntax errors but they are not the problem.
I have tried the script written by sachinwadhwa  but I get errors (sorry but some of the text is in spanish)
------------------------------ Mandatos entrados ------------------------------
CREATE TRIGGER DB2INST1.UPDTfiable AFTER
UPDATE OF fiable
ON RUMBO.TBLproveedores
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
MODE DB2SQL
BEGIN
     IF ( o.fiable <> n.fiable) THEN
          IF ( n.fiable = 0 ) THEN
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado = 'PC' WHERE   ART.idproveedor    = ART.idproveedor
          ELSE
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'PC' WHERE   ART.idproveedor   = ART.idproveedor and art.articulocritico = 0 ;
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'OK' WHERE   ART.idproveedor  = n.idproveedor and art.articulocritico = 1;
          END IF;
     END IF;
------------------------------------------------------------------------------
CREATE TRIGGER DB2INST1.UPDTfiable AFTER
UPDATE OF fiable
ON RUMBO.TBLproveedores
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
MODE DB2SQL
BEGIN
IF ( o.fiable <> n.fiable) THEN
IF ( n.fiable = 0 ) THEN
UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado = 'PC' WHERE   ART.idproveedor    = ART.idproveedor
ELSE
UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'PC' WHERE   ART.idproveedor   = ART.idproveedor and art.articulocritico = 0
DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0104N  Se ha encontrado una señal imprevista "<>" a continuación de " BEGIN
IF ( o.fiable".  Entre las señales esperadas se puede incluir: ",".  LINE
NUMBER=8.  SQLSTATE=42601

UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'OK' WHERE   ART.idproveedor  = n.idproveedor and art.articulocritico = 1
DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0206N  "N.IDPROVEEDOR" no es válida en el contexto en el que se utiliza.  
SQLSTATE=42703

END IF
DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0104N  Se ha encontrado una señal imprevista "END-OF-STATEMENT" a
continuación de "END IF".  Entre las señales esperadas se puede incluir: "JOIN
<joined_table>".  SQLSTATE=42601

END IF
DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0104N  Se ha encontrado una señal imprevista "END-OF-STATEMENT" a
continuación de "END IF".  Entre las señales esperadas se puede incluir: "JOIN
<joined_table>".  SQLSTATE=42601

SQL0104N  Se ha encontrado una señal imprevista "END-OF-STATEMENT" a continuación de "END IF".  Entre las señales esperadas se puede incluir: "JOIN <joined_table>                           ".

Explicación:

Se ha detectado un error de sintaxis en la sentencia de SQL en el
símbolo especificado después del texto "<texto>". El campo
"<texto>" indica los 20 caracteres de la sentencia de SQL que
preceden al símbolo que no es válido.  

 Como ayuda al programador, se proporciona una lista parcial de
símbolos válidos en el campo SQLERRM del SQLCA como
"<lista-símbolos>". Esta lista da por supuesto que la sentencia
es correcta hasta ese punto.  

 No se puede procesar la sentencia.  

Respuesta del usuario:

Revise y corrija la sentencia en el área del símbolo
especificado.  

 sqlcode :  -104

 sqlstate :  42601

SOLUTION
Avatar of sachinwadhwa
sachinwadhwa
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pboix

ASKER

Ok, I tried db2 -td% -f file and this is the message I get.


C:\Archivos de programa\IBM\SQLLIB\BIN>db2 -td% -f o:\docs\manuales\desarrolloap
licaciones\triggerupdt.txt

   Información de la conexión con la base de datos

 Servidor bases datos   = DB2/LINUX 8.2.4
 ID autorización SQL    = DB2INST1
 Alias base datos local = FALCASER


DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0104N  Se ha encontrado una señal imprevista "<>" a continuación de "EGIN
IF ( n.fiable".  Entre las señales esperadas se puede incluir: ",".  LINE
NUMBER=8.  SQLSTATE=42601

DB20000I  El mandato SQL ha finalizado satisfactoriamente.
instead of <> use !=

Avatar of pboix

ASKER

sachinwadhwa, I have tried to use != and I got the same error, then I tried to use = for the comparation and place the sentences in else
IF ( n.fiable = o.fiable) then
      ELSE.....
But I got the error. Then I tried to use == instead of =  but the same.

I think it is a syntax problem, this is the file and the error message:

CONNECT TO FALCASER user db2inst1 using db2inst1%
CREATE TRIGGER DB2INST1.UPDTfiable AFTER
UPDATE OF fiable
ON RUMBO.TBLproveedores
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
MODE DB2SQL
BEGIN
      IF ( n.fiable = o.fiable) then
      ELSE
          IF ( n.fiable = 0 ) THEN
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado = 'PC' WHERE   ART.idproveedor    =

ART.idproveedor
          ELSE
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'PC' WHERE   ART.idproveedor   =

ART.idproveedor and art.articulocritico = 0 ;
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'OK' WHERE   ART.idproveedor  =

n.idproveedor and art.articulocritico = 1;
          END IF;
      END IF;
END%
CONNECT RESET%


C:\Archivos de programa\IBM\SQLLIB\BIN>db2 -td% -f o:\docs\manuales\desarrolloap
licaciones\triggerupdt.txt

   Información de la conexión con la base de datos

 Servidor bases datos   = DB2/LINUX 8.2.4
 ID autorización SQL    = DB2INST1
 Alias base datos local = FALCASER


DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0104N  Se ha encontrado una señal imprevista "=" a continuación de "EGIN
IF ( n.fiable".  Entre las señales esperadas se puede incluir: ",".  LINE
NUMBER=8.  SQLSTATE=42601

DB20000I  El mandato SQL ha finalizado satisfactoriamente.

try IF o.fiable = n.fiable then

without brackets !

Avatar of pboix

ASKER

Sorry sachinwadhwa simmilar error!!!  I'm now trying a easier trigger to find the bug.
CONNECT TO FALCASER user db2inst1 using db2inst1%
CREATE TRIGGER DB2INST1.UPDTfiable AFTER
UPDATE OF fiable
ON RUMBO.TBLproveedores
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
MODE DB2SQL
BEGIN
      IF ( o.fiable = n.fiable ) then
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado = 'PC' WHERE   ART.idproveedor    = ART.idproveedor ;
        ELSE
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'PC' WHERE   ART.idproveedor   = ART.idproveedor and art.articulocritico = 0 ;

      END IF;
END%
CONNECT RESET%
Please post the actual error messages you get. You are withholding crucial information whenever you ommit it.
Avatar of pboix

ASKER

the command file:

CONNECT TO FALCASER user db2inst1 using db2inst1%
CREATE TRIGGER DB2INST1.UPDTfiable AFTER
UPDATE OF fiable
ON RUMBO.TBLproveedores
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
MODE DB2SQL
BEGIN
      IF ( o.fiable = n.fiable ) then
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado = 'PC' WHERE   ART.idproveedor    = ART.idproveedor ;
        ELSE
               UPDATE RUMBO.TBLarticulos ART SET idarticuloEstado= 'PC' WHERE   ART.idproveedor   = ART.idproveedor and art.articulocritico = 0 ;

      END IF;
END%
CONNECT RESET%

 


C:\Archivos de programa\IBM\SQLLIB\BIN>db2 -td% -f "o:\docs\manuales\desarrolloA
plicaciones\triggerupdt.txt"

   Información de la conexión con la base de datos

 Servidor bases datos   = DB2/LINUX 8.2.4
 ID autorización SQL    = DB2INST1
 Alias base datos local = FALCASER


DB21034E  El mandato se ha procesado como una sentencia de SQL porque no era
un mandato válido para el procesador de línea de mandatos.  Durante el proceso
SQL se ha devuelto:
SQL0104N  Se ha encontrado una señal imprevista "=" a continuación de "EGIN
IF ( o.fiable".  Entre las señales esperadas se puede incluir: ",".  LINE
NUMBER=8.  SQLSTATE=42601

DB20000I  El mandato SQL ha finalizado satisfactoriamente.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of pboix

ASKER

Ok, it's working. I have created two triggers :


CONNECT TO FALCASER user db2inst1 using db2inst1%
CREATE TRIGGER DB2INST1.UPDTfiable
AFTER UPDATE OF fiable
ON RUMBO.TBLproveedores
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
when (o.fiable<>n.fiable)
BEGIN atomic
          IF  n.fiable = 0  THEN
               UPDATE RUMBO.TBLarticulos SET idarticuloEstado = 'PC' WHERE  idproveedor = n.idproveedor;
          ELSE
               UPDATE RUMBO.TBLarticulos SET idarticuloEstado= 'PC' WHERE idproveedor   = n.idproveedor and articulocritico = 0 ;
               UPDATE RUMBO.TBLarticulos SET idarticuloEstado= 'OK' WHERE idproveedor  = n.idproveedor and articulocritico = 1;
          END IF;
END%
CONNECT RESET%


AND


CONNECT TO FALCASER user db2inst1 using db2inst1%
CREATE TRIGGER DB2INST1.UPDTArtIDestado
before UPDATE OF articulocritico, idproveedor
ON RUMBO.TBLarticulos
REFERENCING OLD AS o NEW AS n
FOR EACH ROW
BEGIN atomic
          IF  n.articulocritico = 1  THEN
               set n.idarticuloEstado = 'PC' ;
          ELSE
            Set n.idarticuloestado =
               CASE
                  WHEN 0 = (Select p.fiable from rumbo.tblproveedores p
                        where p.idproveedor=n.idproveedor)
                     THEN 'OK'
                  ELSE 'PC'
               END;
         END if;      
END%
CONNECT RESET%