none
problema con trigger RRS feed

  • Pregunta

  • buenos dias, estoy intentando hacer un trigger y me da error de sintaxis cerca de la palabra then

    CREATE TRIGGER [dbo].[fechascob]
    	ON [dbo].[cob]
    	AFTER INSERT, UPDATE
    AS
      BEGIN
        IF TRIGGER_NESTLEVEL()>1
    	RETURN
    	IF imptot >1 AND imptot<1.50 AND tipapa=7 THEN
    	INSERT ("codins", "cod", "fechor", "hor", "tipapa", "numapa", "codtur", "num", "imptot", "porimp", "codforpag", "numtarcre", "numcue","impent", "obs", "solcop") INTO cob VALUES (NEW.codins, NEW.cod+5, NEW.fechor, NEW.hor, NEW.tipapa, NEW.numapa, NEW.codtur, NEW.num, imptot+0.60, NEW.porimp, NEW.codforpag, NEW.numtarcre, NEW.numcue, NEW.impent, NEW.obs, NEW.solcop, NEW.codcli, NEW.codop, NEW.anu, NEW.fechorret, NEW.fechoranu);
    	ENDIF
        UPDATE cob
      	SET
       		fechor = DATEADD (YEAR, 8, fechor),
      		fechorret = DATEADD (YEAR, 8, fechorret),
      		fechoranu = DATEADD (YEAR, 8, fechoranu)
        WHERE cod = (SELECT cod FROM INSERTED)
     		
      END
    

    miércoles, 2 de diciembre de 2020 11:57

Todas las respuestas

  •     IF NEW.imptot >1 AND NEW.imptot<1.50 AND NEW.tipapa=7 THEN
        INSERT ("codins", "cod", "fechor", "hor", "tipapa", "numapa", "codtur", "num", "imptot", "porimp", "codforpag", "numtarcre", "numcue","impent", "obs", "solcop") INTO cob VALUES (NEW.codins, NEW.cod+5, NEW.fechor, NEW.hor, NEW.tipapa, NEW.numapa, NEW.codtur, NEW.num, imptot+0.60, NEW.porimp, NEW.codforpag, NEW.numtarcre, NEW.numcue, NEW.impent, NEW.obs, NEW.solcop, NEW.codcli, NEW.codop, NEW.anu, NEW.fechorret, NEW.fechoranu);
         ENDIF;
        UPDATE cob


    aqui tengo el error, pero no lo localizo


    • Editado Javierdtv miércoles, 2 de diciembre de 2020 12:17
    miércoles, 2 de diciembre de 2020 12:17
  • Hola Javierdtv:

    Esa sintaxis no parece de TSQL, sino más bien de otro tipo de SGBD. 

    En Tsl If no lleva then ni endif, solo puede llevar begin y end. if (....) begin ...end

    Los insert no siguen esa codificación y se utiliza la pseudo-tabla inserted no new.

    Si estas utilizando otra base de datos, que no es SQL Server de Microsoft, deberías de utilizar otro foro donde te puedan asesorar mejor de las particularidades de cada lenguaje.

    Si es TSQL el trigger por sintaxis podría ser así:

    CREATE TRIGGER [dbo].[fechascob]
    	ON [dbo].[cob]
    	AFTER INSERT, UPDATE
    AS
      BEGIN
        IF TRIGGER_NESTLEVEL()>1
    		RETURN;
    	IF (imptot >1 AND imptot<1.50 AND tipapa=7)
    	Begin
    		INSERT into cob ([codins], [cod], [fechor], [hor], [tipapa], [numapa], [codtur], [num], [imptot], [porimp], [codforpag], [numtarcre], [numcue],[impent], [obs], [solcop]) 
    		select I.codins, I.cod+5, I.fechor, I.hor, I.tipapa, I.numapa, I.codtur, I.num, imptot+0.60, I.porimp, I.codforpag, I.numtarcre, I.numcue, I.impent, I.obs, I.solcop, I.codcli, I.codop, I.anu, I.fechorret, I.fechoranu
    		From inserted I;
    	end
        UPDATE cob
      	SET
       		fechor = DATEADD (YEAR, 8, fechor),
      		fechorret = DATEADD (YEAR, 8, fechorret),
      		fechoranu = DATEADD (YEAR, 8, fechoranu)
        WHERE cod = (SELECT cod FROM INSERTED);
     		
      END

    miércoles, 2 de diciembre de 2020 13:59
  • Hay una cosa más que no había visto, por desconocimiento de las tablas

    WHERE cod = (SELECT cod FROM INSERTED)

    Si la tabla cod no contiene un campo que se llama cod, esto fallará.

    Además si en vez de un registro se updatean varios esto no funcionará correctamente.

    Puedes hacer un 

        UPDATE c
      	SET
       		fechor = DATEADD (YEAR, 8, i.fechor),
      		fechorret = DATEADD (YEAR, 8, i.fechorret),
      		fechoranu = DATEADD (YEAR, 8, i.fechoranu)
    	from cob as c  inner join inserted i on c.cob = i.cob

    Tomando como base que la tabla cob tiene como primary key una columna llamada cob.

    Trigger after insert

    https://javifer2.wordpress.com/2020/04/12/trigger-que-es-como-se-hace-y-como-funciona-after-for-insert/

    Trigger after update

    https://javifer2.wordpress.com/2020/04/15/trigger-que-es-como-se-hace-y-como-funciona-after-for-update/


    miércoles, 2 de diciembre de 2020 14:03
  • Es Microsoft, la versión de 2000, como habrás comprobado soy novato y lo he ido haciendo con la información que he encontrado en internet
    • Editado Javierdtv miércoles, 2 de diciembre de 2020 15:22 Datos
    miércoles, 2 de diciembre de 2020 14:34
  • La primera columna es cod, si lo tiene
    miércoles, 2 de diciembre de 2020 14:34
  • Lo que tengo que hacer es, cuando entre un registro a esta tabla, primero comprar la condición del if, si se cumple, duplicar el registro modificando dos variables y después que se actualice la fecha sumándole 8 años
    miércoles, 2 de diciembre de 2020 14:37
  • Hola Javierdtv:

    ¿De verdad tienes SQL Server 2000? A mi me queda superlejos, ya no me acuerdo de nada, aunque puede ser algo así.

    Solo para asegurarte, puedes consultar Select @@version

    Probablemente sea tal que:

    CREATE TRIGGER [dbo].[fechascob]
    	ON [dbo].[cob]
    	AFTER INSERT, UPDATE
    AS
      BEGIN
        IF TRIGGER_NESTLEVEL()>1
    		RETURN;
    	
        UPDATE c
      	SET
       		fechor =	DATEADD (YEAR, 8, inserted.fechor),
      		fechorret = DATEADD (YEAR, 8, inserted.fechorret),
      		fechoranu = DATEADD (YEAR, 8, inserted.fechoranu)
        FROM COB c INNER JOIN INSERTED i  ON c.COB = i.COB
    	WHERE 
    			i.IMPTOT>1 
    		AND i.imptot<1.50
    		AND i.tipapa=7 
     		
      END

    La condición en vez de hacerla con variables la haces con la propia sentencia update. Relacionas los registros con la pseudo tabla inserted para que solo, sea los que se insertan o updatean.

    jueves, 3 de diciembre de 2020 7:28
  • Si, aún estamos con este prográmelos. Dentro de mi limitado entender, creo que en el código que me has puesto solo cambia la fecha a los que cumplen la condición de imptot y tiapa. La ideas es que, los que cumplen la condición de tipapa e imptot, se duplique el registro y le modifiquen las columnas cod e imptot. Y una vez hecho eso, se modifique la fecha a todos los nuevos registros independientemente de si cumplen la condición de imptot y tipapa. Muchas gracias por tu ayuda
    jueves, 3 de diciembre de 2020 17:57
  • Hola Javierdtv:

    Ok, entonces puede ser como esto, aprox:

    create table cob (cob int, fechor date, fechorret date, fechoranu date, impTot float, tipapa int)
    go
    insert into cob (cob, fechor, fechorret, fechoranu, impTot, tipapa)
    values
    (1,getdate(),getdate(), getdate(), 1,1)
    go

    Tenemos una tabla y 1 registro. 

    Ahora creo el trigger pero solo de insert, porque no veo de lo que comentas que sea necesario también el de update.

    CREATE TRIGGER [dbo].[fechascob]
    	ON [dbo].[cob]
    	AFTER INSERT
    AS
      BEGIN
    	
    	-- duplicamos el registro si se cumple la condición.
    	Insert into cob (cob, fechor, fechorret, fechoranu, impTot, tipapa)
    	Select i.cob, 
    	i.fechor, i.fechorret, i.fechoranu, 
    	i.impTot, i.tipapa 
    	from inserted i
    		where 
    			i.IMPTOT>1 
    			AND i.imptot<1.50
    			AND i.tipapa=7;
    
        UPDATE c
      	SET
       		fechor =	DATEADD (YEAR, 8, i.fechor),
      		fechorret = DATEADD (YEAR, 8, i.fechorret),
      		fechoranu = DATEADD (YEAR, 8, i.fechoranu)
        FROM COB c INNER JOIN INSERTED i  ON c.COB = i.COB
     		
      END
    GO

    Hacemos la inserción con una select sobre la pseudotabla inserted, pero solo si cumplen la condición, sino no se duplican.

    Y luego, la update sobre los registros insertados.

    Ahora hacemos una prueba insertando dos registros. Uno cumple la condición, y otro no. Pero los insertamos en la misma sentencia.

    insert into cob (cob, fechor, fechorret, fechoranu, impTot, tipapa)
    values
    (2,getdate(),getdate(), getdate(), 1.25,7),
    (3,getdate(),getdate(), getdate(), 1.25,6);
    go
    SELECT * FROM dbo.cob

    Como puedes ver el registro 2 está duplicado.

    Tendrás que tener en cuenta, que yo no tengo clave primaria, y por tanto puedo duplicarlo. Si en tu caso tienes una primary key o alguna restricción unique de alguna columna no funcionará. 

    Espero te ayude


    jueves, 3 de diciembre de 2020 21:09