none
Consulta con insert en 3 tablas Procedimiento Almacenado RRS feed

  • Pregunta

  • select 
    NEMPLEADO,
    NCLIENTE,
    CNOMBRE 
    from empleados a 
    inner join CLIENTEOPERADORES b on cl.CEMPLEADO=a.NEMPLEADO
    where a.PUESTO in (34,38)


    yo tengo la siguiente consulta la cual debo de crear un usuario en base a cada registro que me regrese. La tabla de USUARIOS tiene los siguientes campos:

    IDusuario Identity int
    cNombre varchar(200)

    En esta tabla solo guardar IDusuario que se genera solo porque es identity,
    Y el nombre de cada registro que me regrese la consulta.


    Tengo otro tabla USUARIOPERFIL que tiene el Perfil del usuario que debo guardar:

    nPerfilUsuario identity int 
    Perfil int que en este caso seria 7 por default
    nIDusuario int 

    En esta tabla tengo que guardar nPerfilUsuario que se genera solo porque es identity, el Perfil que seria 7 para todos y el nIDusuario de cada registro nuevo, que fue insertado en la tabla Usuarios (NOTA EN LA TABLA DE USUARIOS YA HAY REGISTROS INSERTADOS Y necesito que solo se inserten en esta tabla los nuevos que vienen de la consulta)

    Tengo otro tabla ClientesOperador que tiene los siguientes campos
    nID identity int 
    nIdUsuario int 
    nClaveCliente int 

    En esta tabla tengo que guardar nID que se genera solo porque es identity,
    el nIDusuario de cada registro nuevo, que fue insertado en la tabla Usuarios ,
    (NOTA EN LA TABLA DE USUARIOS YA HAY REGISTROS INSERTADOS Y necesito que solo se inserten en esta tabla los nuevos que vienen de la consulta),
    En el campo nClaveCliente se guardara el NCLIENTE que viene de la consulta correspondiente a cada registro.


    jueves, 17 de octubre de 2019 3:34

Respuestas

  • Hola Adalberto88:

    from empleados a inner join CLIENTEOPERADORES b on cl.CEMPLEADO=a.NEMPLEADO

    Eso no puede funcionar, ya que cl.CEMPLEADO, no existe.

    Por otro lado, dado que tú escenario es un poco cambiante, para insertar por cada registro de un conjunto 4 filas de otro conjunto:

    Declare @tableUsuarios table (Nemepleado int, Ncliente int)
    insert into @tableUsuarios (Nemepleado, Ncliente)
    values
    (1,1),
    (2,25),
    (2025,28);
    Declare @tableDerechosPerfil table (idDerecho int identity(1093,1), Perfil int, Modulo int)
    Insert into @tableDerechosPerfil (Perfil, Modulo)
    values
    (7,14),
    (7,17),
    (7,18),
    (7,13);
    
    Declare @tableDerechos table (id int identity(1,1), idUsuario int, idDerecho int)
    
    ;with cte as (
        Select Nemepleado, Ncliente
         from @tableUsuarios
    	WHERE Nemepleado = 2025
        ), cte2 as 
        (select idDerecho, 
    	   perfil,
    	   Modulo
    	   from @tableDerechosPerfil where perfil=7
    )
    insert into @tableDerechos
    select cte.Nemepleado, cte2.idDerecho
    from cte cross join cte2
    
    select * from @tableDerechos
    Cross join realiza un producto cartesiano de cada fila de un conjunto por cada una del otro conjunto.

    • Propuesto como respuesta Pablo RubioModerator viernes, 18 de octubre de 2019 18:22
    • Marcado como respuesta Adalberto88 sábado, 19 de octubre de 2019 0:10
    viernes, 18 de octubre de 2019 4:17

Todas las respuestas

  • Hola Adalberto88:

    Una solución a tu requisito, puede ser

    CREATE TABLE EMPLEADOS (NEMPLEADO INT, PUESTO INT)
    CREATE TABLE CLIENTEOPERADORES (CEMPLEADO INT, NCLIENTE INT, CNOMBRE VARCHAR(100))
    GO
    
    INSERT INTO EMPLEADOS 
    (NEMPLEADO, PUESTO)
    VALUES
    (1,34),
    (2,38),
    (3,34),
    (4,38),
    (5,34);
    INSERT INTO CLIENTEOPERADORES 
    (CEMPLEADO, NCLIENTE, CNOMBRE)
    VALUES
    (1,1,'ALBA'),
    (2,2,'VERÓNICA'),
    (3,3,'CRISTOBAL'),
    (1,4,'LUISA'),
    (5,5,'FEDE'),
    (2,6,'PEDRO');
    GO
    CREATE TABLE USUARIOS
    (IDusuario INT IDENTITY(1,1), Cnombre varchar(200));
    GO
    CREATE TABLE USUARIOPERFIL
    (NPerfilUsuario INT IDENTITY(1,1),
    Perfil int NOT NULL default (7),
    nlDusuario int);
    GO
    CREATE TABLE ClientesOPERADOR
    (NId INT IDENTITY(1,1),nIdUsuario int,nClaveCliente int)
    GO
    /* GENERAMOS DOS REGISTROS A USUARIOS */  
    INSERT INTO USUARIOS 
    SELECT ('CARLOS')
    UNION ALL
    SELECT('ANA');
    GO
    CREATE PROCEDURE sp_Registro
    AS
    BEGIN
    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
    BEGIN TRANSACTION 
    
    BEGIN TRY
        /* PARA EJECUTAR LA CONSULTA UNA SOLA VEZ, LA GUARDAMOS EN UNA VARIABLE TIPO TABLA */
        DECLARE @TABLE TABLE (NEMPLEADO INT, NCLIENTE INT, CNOMBRE VARCHAR(200))
        INSERT INTO @TABLE
        SELECT
        NEMPLEADO,
        NCLIENTE,
        CNOMBRE 
        from empleados a 
        inner join CLIENTEOPERADORES b on b.CEMPLEADO=a.NEMPLEADO
        where a.PUESTO in (34,38);
    
        DECLARE @USER INT;
        SET @USER = (SELECT ISNULL(MAX(IDUSUARIO),0) FROM USUARIOS);
        /*En esta tabla solo guardar IDusuario que se genera solo porque es identity,
    Y el nombre de cada registro que me regrese la consulta.*/
        INSERT INTO USUARIOS
        SELECT CNOMBRE FROM @TABLE;
    
        /* En esta tabla tengo que guardar nPerfilUsuario que se genera solo porque es identity, el Perfil que seria 7 para todos y el nIDusuario de cada registro nuevo, que fue insertado en la tabla Usuarios (NOTA EN LA TABLA DE USUARIOS YA HAY REGISTROS INSERTADOS Y necesito que solo se inserten en esta tabla los nuevos que vienen de la consulta) */
        INSERT INTO USUARIOPERFIL
        SELECT 7,IDUSUARIO 
        FROM USUARIOS WHERE IDusuario > @USER;
    
        INSERT INTO ClientesOPERADOR 
        SELECT U.IDusuario, T.NCLIENTE FROM USUARIOS U INNER JOIN @TABLE T 
        ON U.Cnombre = T.CNOMBRE
        WHERE U.IDusuario > @USER
    
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        THROW 50000,N'Ha ocurrido un error',1;
    
    END CATCH
    END
    GO
    
    EXEC sp_Registro
    GO
    SELECT * FROM USUARIOS
    SELECT * FROM ClientesOPERADOR
    SELECT * FROM USUARIOPERFIL

    Salida

    Espero te ayude

    jueves, 17 de octubre de 2019 4:17
  • ¿Está la columna NCLIENTE en la tabla EMPLEADOS o en la tabla CLIENTESOPERADORES?

    ¿La columna CNOMBRE está en la tabla EMPLEADOS o en la tabla CLIENTESOPERADORES?

    ¿Es posible incluir filas con valores CNOMBRE repetidos en la tabla USUARIOS?

    En la tabla ClientesOperador ¿debe rellenarse la columna nClaveCliente con el valor nIDusuario de la tabla USUARIOPERFIL o con el IDUsuario de la tabla USUARIOS?

     

    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    jueves, 17 de octubre de 2019 9:17
  • En la tabla empleados esta la columna NCLIENTE  y en la tabla CLIENTESOPERADORES nClavecliente que corresponde, lo que venga de la consulta en ncliente tiene que ser insertado en nClavecliente.

    La columna CNOMBRE esta en la tabla EMPLEADOS, corresponde a la tabla USUARIOS también a la columna CNOMBRE  

    Es posible incluir filas con valores CNOMBRE repetidos en la tabla USUARIOS? si se llegará a dar el caso si es posible

    En la tabla ClientesOperador ¿debe rellenarse la columna nClaveCliente con el valor nIDusuario de la tabla USUARIOPERFIL o con el IDUsuario de la tabla USUARIOS? EL nClaveCliente no se llena con el nIDusuario sino con el NCLIENTE del select 

    jueves, 17 de octubre de 2019 11:56
  • En la tabla empleados esta la columna NCLIENTE (...)
    La columna CNOMBRE esta en la tabla EMPLEADOS (...)

    Si las columnas NEMPLEADO, NCLIENTE y CNOMBRE están en la tabla EMPLEADOS, ¿cuál es la razón de la unión con la tabla CLIENTEOPERADORES en el código SQL que publicó?

    select 
    NEMPLEADO,
    NCLIENTE,
    CNOMBRE 
    from empleados a 
    inner join CLIENTEOPERADORES b on cl.CEMPLEADO=a.NEMPLEADO
    where a.PUESTO in (34,38)


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    jueves, 17 de octubre de 2019 12:12
  • Se me paso otra parte en la que no pensé, tengo otra tabla que se llama 

    DerechosPerfil

    IdDerecho int identy

    Perfil int

    Modulo int

    Haria una consulta así para recuperar los datos que necesito de esa tabla

    select 
    IdDerecho ,
    Perfil,
    Modulo
    from DerechosPerfil where Perfil=7

    por cada usuario de la primera consulta, insertado en la tabla USUARIOS, tengo que insertar los cuatros registros que me regresa esta consulta en la siguiente tabla:

    DerechosUsuario

    Id identity int,

    IdUsuario int,

    IdDerecho int

    Un ejemplo de un Usuario insertado así debe de quedar:

    jueves, 17 de octubre de 2019 12:37
  • Es posible incluir filas con valores CNOMBRE repetidos en la tabla USUARIOS? si se llegará a dar el caso si es posible

    Puesto que pueden existir valores repetidos para la columna CNOMBRE, no veo cómo puede incluir filas en la tabla ClientesOperador.

    ---

    -- código #1
    --
    declare @insU table (IDusuario int);
    
    INSERT into USUARIOS (cNombre)
      output inserted.IDusuario into @insU
      SELECT CNOMBRE 
        from empleados a 
             inner join CLIENTEOPERADORES b on b.CEMPLEADO = a.NEMPLEADO
        where a.PUESTO in (34,38);
    
    --
    INSERT into USUARIOPERFIL (Perfil, nIDusuario)
      SELECT 7, T.IDusuario
        from @insU as T;
    
    --
    INSERT into ClientesOperador (nIdUsuario, nClaveCliente)
      SELECT T.IDusuario, ?
        from @insU as T;
    



    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    jueves, 17 de octubre de 2019 12:39
  • Suponiendo que haya un campo único en esta consulta por el que los puedo amarrar, por ejemplo el campo UNICO tipo int que venga de la tabla empleados

    select 
    NEMPLEADO,
    NCLIENTE,
    CNOMBRE,
    UNICO,
    from empleados a 
    inner join CLIENTEOPERADORES b on cl.CEMPLEADO=a.NEMPLEADO
    where a.PUESTO in (34,38)

    como puedo continuar con el flujo?

    incluyendo esta parte:

    tengo otra tabla que se llama 

    DerechosPerfil

    IdDerecho int identy

    Perfil int

    Modulo int

    Haria una consulta así para recuperar los datos que necesito de esa tabla

    select 
    IdDerecho ,
    Perfil,
    Modulo
    from DerechosPerfil where Perfil=7

    por cada usuario de la primera consulta, insertado en la tabla USUARIOS, tengo que insertar los cuatros registros que me regresa esta consulta en la siguiente tabla:

    DerechosUsuario

    Id identity int,

    IdUsuario int,

    IdDerecho int

    Un ejemplo de un Usuario insertado así debe de quedar:


    • Editado Adalberto88 jueves, 17 de octubre de 2019 13:34
    jueves, 17 de octubre de 2019 13:32
  • Hola Adalberto88:

    from empleados a inner join CLIENTEOPERADORES b on cl.CEMPLEADO=a.NEMPLEADO

    Eso no puede funcionar, ya que cl.CEMPLEADO, no existe.

    Por otro lado, dado que tú escenario es un poco cambiante, para insertar por cada registro de un conjunto 4 filas de otro conjunto:

    Declare @tableUsuarios table (Nemepleado int, Ncliente int)
    insert into @tableUsuarios (Nemepleado, Ncliente)
    values
    (1,1),
    (2,25),
    (2025,28);
    Declare @tableDerechosPerfil table (idDerecho int identity(1093,1), Perfil int, Modulo int)
    Insert into @tableDerechosPerfil (Perfil, Modulo)
    values
    (7,14),
    (7,17),
    (7,18),
    (7,13);
    
    Declare @tableDerechos table (id int identity(1,1), idUsuario int, idDerecho int)
    
    ;with cte as (
        Select Nemepleado, Ncliente
         from @tableUsuarios
    	WHERE Nemepleado = 2025
        ), cte2 as 
        (select idDerecho, 
    	   perfil,
    	   Modulo
    	   from @tableDerechosPerfil where perfil=7
    )
    insert into @tableDerechos
    select cte.Nemepleado, cte2.idDerecho
    from cte cross join cte2
    
    select * from @tableDerechos
    Cross join realiza un producto cartesiano de cada fila de un conjunto por cada una del otro conjunto.

    • Propuesto como respuesta Pablo RubioModerator viernes, 18 de octubre de 2019 18:22
    • Marcado como respuesta Adalberto88 sábado, 19 de octubre de 2019 0:10
    viernes, 18 de octubre de 2019 4:17
  • Muchisimas Gracias Pablo Rubio respuesta probrada al 100%
    sábado, 19 de octubre de 2019 0:10