none
copiar campos de uan tabla a otra con foreing key RRS feed

  • Pregunta

  • los pongo en antecedentes, tengo una tabla la cual necesito quitarle mas de 5 mil registros repetidos, esta tabla se llama permisos, y alo hice, pero tuve que mandar todo una segunda tabla,  son 196 mil registros los que mande a la segunda tabla que es tbapermisos2, ahora necesito copiar todo lo de la tabla permisos2 a la original, con esta consulta

    INSERT INTO tbapermisos(App, IdNum, IdGrupo, Forma, Objeto, Habilitado, AlaVista, ValorPredeterminado, IdConsec, Descripcion)
    SELECT *
    FROM tbapermisos2;

    el punto esta en que la tabla original tiene 8 indices 1 primari key y un foreing key, com puedo hacer que esta tabla reciba todo lo que esta en la 2


    sábado, 16 de marzo de 2019 20:54

Todas las respuestas

  • Hola cesar rios:

    Según lo que has escrito yo entiendo, que en la tabla original tienes 201.000 registros actualmente, y en la tabla permisos2 tienes 196.000, entonces, no tendrás que hacer un insert.

    Suponiendo que original = 0

    Entonces haces un insert como has puesto.

    Ahora bien, que tenga 8 índices, ni fu ni fa, que tenga una primary key ni fu ni fa. Que tenga una foreign key esto ya es harina de otro costal, porque si según tú sólo has borrado 5000 registros de tabla2 y tabla2 no ha cambiado, esa tabla a la que hace referencia tus registros de tabla2 aún tendrá el registro al que hace referencia. ¿o no?

    En cualquiera de los dos escenarios, yo intentaría hacer un merge.

    create table tbaPermisos(App bit, idNum bit, idGrupo bit, Forma bit, Objeto bit, Habilitado bit, AlaVista bit, ValorPredeterminado bit, idconsec int identity(1,1) primary key, Descripcion bit)
    go
    insert into tbaPermisos (App , idNum , idGrupo , Forma , Objeto , Habilitado , AlaVista , ValorPredeterminado , Descripcion )
    values
    (1,0,1,1,1,1,1,1,1),
    (0,0,1,1,1,1,1,1,1),
    (0,1,1,1,1,1,1,1,1),
    (0,0,1,0,1,1,1,1,1),
    (0,0,1,1,0,1,1,1,1),
    (0,0,1,1,1,1,1,1,1),
    (0,0,1,1,1,0,1,1,1),
    (0,0,1,1,1,1,1,0,1),
    (0,0,1,1,1,1,1,1,0),
    (0,1,1,0,1,1,1,1,1),
    (1,1,1,1,1,1,1,1,1),
    (0,0,1,0,0,1,0,0,0);
    go
    create table tbaPermisos2(App bit, idNum bit, idGrupo bit, Forma bit, Objeto bit, Habilitado bit, AlaVista bit, ValorPredeterminado bit, idconsec int primary key, Descripcion bit)
    go
    insert into tbaPermisos2
    select top(10) * from tbaPermisos
    order by App, Forma, Objeto, idconsec
    go
    SELECT tbaPermisos2.App, 
           tbaPermisos2.idNum, 
           tbaPermisos2.idGrupo, 
           tbaPermisos2.Forma, 
           tbaPermisos2.Objeto, 
           tbaPermisos2.Habilitado, 
           tbaPermisos2.AlaVista, 
           tbaPermisos2.ValorPredeterminado, 
           tbaPermisos2.idconsec, 
           tbaPermisos2.Descripcion
    FROM tbaPermisos2;
    /* En tbaPermisos2 tengo 10 registros y en tbaPermisos 12 */
    go

    Con este escenario, creado, todos los campos los he definido como bit, por simplicidad, excepto la clave primaria de ambas tablas, que esta como int e identitaria.

    Merge tbaPermisos as target
    using (
    SELECT tbaPermisos2.App, 
           tbaPermisos2.idNum, 
           tbaPermisos2.idGrupo, 
           tbaPermisos2.Forma, 
           tbaPermisos2.Objeto, 
           tbaPermisos2.Habilitado, 
           tbaPermisos2.AlaVista, 
           tbaPermisos2.ValorPredeterminado, 
           tbaPermisos2.idconsec, 
           tbaPermisos2.Descripcion
    FROM tbaPermisos2) as Source
    (
    App, idNum, idGrupo, Forma, Objeto, Habilitado, AlaVista, ValorPredeterminado, idconsec, Descripcion)
    on (target.idconsec = source.idconsec) /* La clausula on identifica a los registros por su clave primaria en tu caso */
    when matched then update set
    	target.app					= source.app,
    	target.idnum				= source.idnum, 
    	target.Forma 				= source.Forma, 
        target.Objeto 				= source.Objeto, 
        target.Habilitado 			= source.Habilitado, 
        target.AlaVista 			= source.AlaVista, 
        target.ValorPredeterminado  = source.ValorPredeterminado,
    --    target.idconsec 			= source.idconsec, No necesario, clave primaria 
        target.Descripcion			= source.Descripcion
    when not matched by source then delete /* si en destino existen y en origen no, elimino */
    when not matched then insert
    ( App , idNum , idGrupo , Forma , Objeto , Habilitado , AlaVista , ValorPredeterminado , Descripcion )
    /* si tu clave primaria en destino es identity, tendrás que parar el mismo, e incluir la insercción la columna, en mi caso no lo ejecuto así */
    values (source.app,
    		source.idnum, 
    		source.idGrupo,
    		source.Forma, 
    		source.Objeto, 
    		source.Habilitado, 
    		source.AlaVista, 
    		source.ValorPredeterminado,
    		/*source.idconsec,  */
    		source.Descripcion
    		);

    Si observas la sentencia merge, incluye un WHEN Not matched by source then delete, que borra los registros de destino que no existen en origen.

    Merge

    https://docs.microsoft.com/es-es/sql/t-sql/statements/merge-transact-sql?view=sql-server-2017

    • Propuesto como respuesta Carlos_Ruiz_M jueves, 21 de marzo de 2019 15:52
    domingo, 17 de marzo de 2019 9:03
  • Deleted
    • Propuesto como respuesta Carlos_Ruiz_M jueves, 21 de marzo de 2019 15:52
    domingo, 17 de marzo de 2019 16:51
  • Deleted
    • Propuesto como respuesta Carlos_Ruiz_M jueves, 21 de marzo de 2019 15:52
    domingo, 17 de marzo de 2019 17:09
  • Hola José:

    Gracias por la aportación, pero precisamente eso, es lo que yo entiendo de lo que ha descrito Cesar Rios en su escenario.

    Tenía 201.000 registros y copia 196.000, sin los duplicados que no quería. Ahora quiere volver a la tabla de origen y que contenga los 196.000 de tabla dos, por tanto tiene que borrar los 5000 de origen, más las modificaciones que haya realizado, por eso el MERGE es desde tabla2 como source, hacia tabla1.

    Al menos es lo que yo identifiqué de lo que puso cesar rios.

    El hizo select * into permisos2 from permisos except.... y ahora pasado un tiempo queire que permisos tenga lo que permisos2, pero y aquí viene lo del Merge


    • Propuesto como respuesta Carlos_Ruiz_M jueves, 21 de marzo de 2019 15:52
    domingo, 17 de marzo de 2019 17:25
  • Deleted
    • Propuesto como respuesta Carlos_Ruiz_M jueves, 21 de marzo de 2019 15:52
    domingo, 17 de marzo de 2019 17:57