none
Insertar datos en una tabla siempre y cuando no existan en ella RRS feed

  • Pregunta

  • Cordial saludo, quisiera saber cual seria la estructura que debo utilizar para insertar datos en una tabla, cumpliendo con la condición de que los datos a insertar, no deben existir en la tabla.



    Germanq

    miércoles, 10 de junio de 2020 20:53

Respuestas

  • Hola German David Quinchia Zapata:

    Puedes utilizar dos alternativas. Pero lo primero el escenario.

    Create table ejA (id int, nombre varchar(100))
    go
    Insert into ejA (id, nombre)
    values (1,'a'),
    (2,'b'),
    (3,'c');
    go

    Alternativa 1.

    Utilizar not exists en la propia insert.

    insert into dbo.ejA(id, nombre)
    select d.ID
    	 , d.nombre
    	   from (
    		Select 1 AS id, 'a' AS nombre
    		union all
    		Select 1, 'insert') AS d
    	   where not exists (
    				Select id, nombre
                                    from dbo.ejA AS e
                                    where d.id = e.id and d.nombre = e.nombre
    			   );
    go

    Si observas la sentencia, he montado una tabla derivada, para insertar dos filas a la vez y evaluar la existencia una sola vez. No es lo importante del ejemplo.

    La gracia está en que la select que va a darle datos a la insert, tiene en el where not exists y dentro hace una select contra dbo.ejA con el alias e. Luego iguala el id del conjunto interno "e.id" con el id del conjunto externo "d.id" y lo mismo con el nombre. Así si coincide un registro por id y nombre, existe por tanto no lo inserta.

    Alternativa 2

    Merge

    Merge dbo.ejA as Target
    	using (select 1,'a'
    		union all
    			Select 1,'merge'
    	) as source (id, nombre)
    on (target.id = source.id and target.nombre = source.nombre)
    
    when not matched by target then 
    	insert (id, nombrE)
    values (source.id, source.nombre);
    go

    La estructura de merge dice, que el target es la tabla a insertar.

    Para el origen he utilizado, igual que antes una Selección con Union all, para intentar insertar dos filas a la vez.

    En merge este sería Source. donde el id de target y el id de source sean iguales y lo mismo para el nombre.

    Y la gracia. When not matched by target

    entonces inserta los valores que disponga source.

    El resultado.

    Merge

    https://javifer2.wordpress.com/2019/10/04/merge-upsert-insertar-o-actualizar-en-una-sola-sentencia/

    Tablas derivadas

    https://javifer2.wordpress.com/2019/11/06/tabla-derivada/

    Union All

    https://javifer2.wordpress.com/2020/04/07/union-vs-union-all/

    Exists

    https://docs.microsoft.com/es-es/sql/t-sql/language-elements/exists-transact-sql?view=sql-server-ver15


    jueves, 11 de junio de 2020 3:23

Todas las respuestas

  • IF NOT EXISTS(SELECT *..........................)

    BEGIN

     INSERT.................

    END


    IIslas Master Consultant SQL Server

    miércoles, 10 de junio de 2020 22:59
  • Hola German David Quinchia Zapata:

    Puedes utilizar dos alternativas. Pero lo primero el escenario.

    Create table ejA (id int, nombre varchar(100))
    go
    Insert into ejA (id, nombre)
    values (1,'a'),
    (2,'b'),
    (3,'c');
    go

    Alternativa 1.

    Utilizar not exists en la propia insert.

    insert into dbo.ejA(id, nombre)
    select d.ID
    	 , d.nombre
    	   from (
    		Select 1 AS id, 'a' AS nombre
    		union all
    		Select 1, 'insert') AS d
    	   where not exists (
    				Select id, nombre
                                    from dbo.ejA AS e
                                    where d.id = e.id and d.nombre = e.nombre
    			   );
    go

    Si observas la sentencia, he montado una tabla derivada, para insertar dos filas a la vez y evaluar la existencia una sola vez. No es lo importante del ejemplo.

    La gracia está en que la select que va a darle datos a la insert, tiene en el where not exists y dentro hace una select contra dbo.ejA con el alias e. Luego iguala el id del conjunto interno "e.id" con el id del conjunto externo "d.id" y lo mismo con el nombre. Así si coincide un registro por id y nombre, existe por tanto no lo inserta.

    Alternativa 2

    Merge

    Merge dbo.ejA as Target
    	using (select 1,'a'
    		union all
    			Select 1,'merge'
    	) as source (id, nombre)
    on (target.id = source.id and target.nombre = source.nombre)
    
    when not matched by target then 
    	insert (id, nombrE)
    values (source.id, source.nombre);
    go

    La estructura de merge dice, que el target es la tabla a insertar.

    Para el origen he utilizado, igual que antes una Selección con Union all, para intentar insertar dos filas a la vez.

    En merge este sería Source. donde el id de target y el id de source sean iguales y lo mismo para el nombre.

    Y la gracia. When not matched by target

    entonces inserta los valores que disponga source.

    El resultado.

    Merge

    https://javifer2.wordpress.com/2019/10/04/merge-upsert-insertar-o-actualizar-en-una-sola-sentencia/

    Tablas derivadas

    https://javifer2.wordpress.com/2019/11/06/tabla-derivada/

    Union All

    https://javifer2.wordpress.com/2020/04/07/union-vs-union-all/

    Exists

    https://docs.microsoft.com/es-es/sql/t-sql/language-elements/exists-transact-sql?view=sql-server-ver15


    jueves, 11 de junio de 2020 3:23
  • Hola Javi, muchas gracias por la respuesta. Me enseñaste ademas de lo que necesitaba, muchas cosas mas.

    Germanq

    jueves, 11 de junio de 2020 13:15
  • Hola Germanq:

    De nada. Es un placer poder aportar un granito de conocimiento.

    jueves, 11 de junio de 2020 14:17