none
como saber si se ingresa un registro por primera vez sql server con un trigger RRS feed

  • Pregunta

  • he tratado de crear un trigger para saber si el registro se inserto por primera vez y si el registro ya existe pero no me ha servido el codigo que utilice es el siguiente por favor necesito ayuda.

    create trigger [dbo].[insregistro]
    on [dbo].[clientes] 
    after insert
    as
    declare @orden varchar(50)
    select @orden = Numero_de_orden from inserted
    declare @sku varchar(50)
    select @sku = Skus from inserted
    declare @nombre varchar(50)
    select @nombre = Nombre from inserted
    declare @fechapedido char(50)
    select @fechapedido = Fecha_pedido from inserted
    declare @correo varchar(50)
    select @correo = Correo from inserted

    if exists (select Nombre from clientes) 
    begin
    print ('Segunda  vez') 
    end
    if not exists (select Nombre from clientes)
    begin 
    print('Primera vez')
    end



    martes, 27 de agosto de 2019 17:28

Todas las respuestas

  • Si se dispara el trigger "after insert" quiere decir que el registro se insertó por primera vez, forzosamente. Si modificas un registro existente, no se dispara el trigger de Insert, sino el Update.

    Y como es "after" Insert, quiere decir que cuando se dispara el trigger el registro YA se ha insertado.

    Otra cosa distinta es que ya exista otro registro idéntico y con los mismos datos y lo hayamos duplicado. Pero desde el punto de vista del trigger, eso es indiferente. Para el trigger, el registro que se acaba de insertar y que desencadena el trigger siempre se ha insertado por primera vez. Pero eso no tiene nada que ver; el registro que acabas de insertar siempre se inserta por primera vez.

    Si quieres buscar duplicados puedes hacer esto:

    if exists (select 1 from clientes join Inserted on clientes.Nombre=inserted.Nombre) 
         print ('Nombre duplicado') 
    else
        print ('Primera vez que vemos el nombre')

    Nótese que si insertas varios registros a la vez, esto te dirá que existe un duplicado solo con que alguno de los varios registros esté duplicado, aunque los demás no lo estén.

    EDITADO: No, ahora que lo pienso eso no funcionará. El problema es que se dispara DESPUÉS de haberlo insertado, por lo que siempre te va a decir que hay un duplicado. Habría que hacer algo un poco más complejo, buscando que exista más de una ocurrencia. Algo parecido a lo siguiente:

    if exists (select 1 from clientes join Inserted on clientes.Nombre=inserted.Nombre group by clientes.nombre having count(*)>=2) 

    martes, 27 de agosto de 2019 18:28
  • Hola jose cuapio:

    Lo primero, es que de la sentencia se deduce que las columnas Numero_de_Orden, Skus, fecha_pedido, pertenecen a la tabla de clientes, y eso no encaja con ninguna regla de normalización.

    Normalizar base de datos

    https://platzi.com/blog/normalizar-una-base-de-datos-y-no-morir-en-el-intento/

    Por otro lado, estas tratando el trigger, como si solo se pudiese insertar un registro de cada vez, y eso no es correcto.

    Además de utilizar un trigger, para imprimir con print, en principio, no tiene mucho sentido.

    Le doy una vuelta al concepto, para poder echarte un cable, de un modo más comprensible.

    create table clientes
    (
     orden varchar(50)
    ,sku varchar(50)
    ,nombre varchar(50)
    ,fechapedido char(50)
    ,correo varchar(50)
    )

    Suponiendo que fuese la misma tabla.

    create trigger dbo.insregistro on dbo.clientes
    after insert
    as
    BEGIN
        declare @orden varchar(50)
        declare @sku varchar(50)
        declare @nombre varchar(50)
        declare @fechapedido char(50)
        declare @correo varchar(50)
        Declare @numVeces int;
    /* suponiendo que es un mero ejercicio, para comprender como funciona */
    
    DECLARE miCursor CURSOR FORWARD_ONLY LOCAL STATIC
    for
        select 
          i.orden 
        , I.sku
        , i.nombre
        , i.fechapedido
        , i.correo
        from inserted i;
    
    OPEN miCursor
    Fetch miCursor into 
       @orden,   @sku ,@nombre,  @fechapedido,  @correo;
    
        WHILE (@@FETCH_STATUS = 0)
        BEGIN
        
    	   PRINT 'Registro insertado Nombre: '+@nombre + ', sku : '+@sku +', Orden: '+@orden + ', Fechapedido: '+@fechapedido+', Correo: '+@correo;
    	   
    	   SET @numVeces = (select count(*)as veces from clientes where nombre = @nombre);
    	   
    	   if (@numVeces>1)
    	       PRINT 'El cliente ya existe '+(cast (@numVeces as varchar(10)))+ ' veces';
    	   else 
    	       print 'Cliente primera vez';
    	   
    	   Fetch miCursor into 
    	      @orden,   @sku ,@nombre,  @fechapedido,  @correo;
        END
    CLOSE miCursor
    DEALLOCATE miCursor
    END
    GO
    

    Creo una cursor para recorrer los registros que tiene la pseudo tabla inserted, y así saber que registro se insertaron en esta transaccion.

    Con el cursor recorro el registro, y busco el número de veces, que ya existe en la tabla, e imprimo los resultados.

    Ejecución.

    /* INSERTO TRES REGISTROS */
    INSERT INTO CLIENTES (
    orden,sku,nombre,fechapedido,correo)
    VALUES
    ('A','A','A','A','A'),
    ('B','B','B','B','B'),
    ('C','C','C','C','C');
    GO
    

    Salida

    /* INSERTO TRES REGISTROS */
    INSERT INTO CLIENTES (
    orden,sku,nombre,fechapedido,correo)
    VALUES
    ('A','A','A','A','A'),
    ('N','N','N','N','N'),
    ('N','N','N','N','N'),
    ('X','X','X','X','X'),
    ('C','C','C','C','C');
    GO
    

    Salida

    Si observas los resultados, la salida es inversa a la insercción, aunque esto no se puede preveer, salvo que pongas un order by en la Select del cursor.

    Cuando pasa el cursor, ya que el trigger es After, el registro ya existe, de ahí que el contador sea mayor que 1.

    Espero te ayude, sino comentas.

    martes, 27 de agosto de 2019 18:33