none
concatenar el nombre de dos tablas oara hacer una consulta... RRS feed

  • Pregunta

  • Hola amigos buenas tardes tengo un detalles necesito concatenar el nombre de dos tablas para hacer un selec por ejemplo tengi una tabla que se llama Unidades de Negocio donde viene por ejemplo ADA Oficina 1, ASA Oficina2 y cada una de ellas tiene creada una tablas donde se guardan los movimientos contables por ejemplo ADA_MOV1, ASA_MOV1 etc... dependiendo de las unidades de negocio creadas, entonces cuando yo quiero hacer una consulta debo poner un parametro de unidad de negocio para que cuando seleccionen ADA pueda buscar en la tabla ADA_MOV1, si seleccionan ASA busque en la tabla ASA_MOV1, quiero decirles que este ya es un sistema echo y yo solo estoy haciendo consultas a la base de datos para hacer reportes espero haberme explicado y agradezco de antemano su apoyo...

    Saludos y bendiciones!...


    _ José Ángel Salinas Paz

    lunes, 23 de enero de 2017 18:57

Respuestas

  • JA Salinas,

    Para nombrar un objeto concatenando una variable a un literal debes utilizar sql dinámico, es decir, debes contener dentro de una cadena una consulta sql válida y luego ejecutarla mediante el procedimiento sp_executesql. Algo que debes tomar en cuenta cuando escribes consultas dinámicas es parametrizar la consulta para evitar la inyección de código malicioso, por ejemplo:

    /*Escribir consulta dinámica*/
    DECLARE @UnidadNegocio nvarchar(4000) = N'W11';
    DECLARE @Tabla sysname = 'dbo.' + QUOTENAME(@UnidadNegocio + '_MOV1');
    DECLARE @ConsultaSQL nvarchar(4000) = 
        N'SELECT Col1, Col2 FROM ' + @Tabla + ' WHERE Col1 = @Col1';
    
    /*Ejecutar consulta*/
    DECLARE @Valor varchar(100) = 'SomeValue';
    EXECUTE sp_executesql @ConsultaSQL, N'@Col1 varchar(10)', @Valor


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 1 de febrero de 2017 15:04

Todas las respuestas

  • JA Salinas,

    Una forma es ejecutar -mediante el procedimiento sp_executesql- una cadena generada de forma dinámica, sin embargo las instrucciones t-sql compiladas en tiempo de ejecución son susceptibles a ataques como SQL Injection. Otra forma es crear una vista que seleccione todas las tablas de movimientos con una columna que describa el nombre de la tabla, la idea es que la expresión de filtro compare el valor del parámetro con el nombre de la tabla, algo como:

    /*Definición de la vista*/
    CREATE VIEW dbo.Movimientos
    AS
        SELECT Col1, Col2, Col3, 'ADA_MOV1' AS NombreTabla FROM ADA_MOV1
        UNION ALL
        SELECT Col1, Col2, Col3, 'ASA_MOV1' FROM ADA_MOV1
        UNION ALL
        SELECT Col1, Col2, Col3, 'ASA_MOV2' FROM ADA_MOV1
    
    
    /*Ejemplo de uso*/
    SELECT * FROM dbo.Movimientos WHERE NombreTabla = @UnidadNegocio;
    GO


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 24 de enero de 2017 4:42
  • Hola Williams fijate que me parecio bueno tu razonamiento pero no funciono, no me trae nada y si vuelvo hacer una consulta me dice que ya existe un objeto llamado Movimientos en la base de datos, pero la primera vez no me trae nada, no se si allgo estoy haciendo mal, pero el resultado de la consulta esta vacio... agradezco de ante mano tu ayuda...


    _ José Ángel Salinas Paz

    martes, 24 de enero de 2017 19:26
  • JA Salinas,

    La creación de la vista se realiza una sola vez, queda claro que si intentas volver a crear la vista obtendrás el error que mencionas porque el objeto ya existe. ¿Qué la vista no retorna resultados? ¿Qué pasa si seleccionas toda las filas sin realizar un filtro (SELECT * FROM dbo.NombreVista)?.

    Si no obtienes resultados es porque el valor del parámetro no produce coincidencias en los datos que contiene la vista, revisa el valor del parámetro y el contenido de la columna [NombreTabla], ¿hay coincidencias?


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 24 de enero de 2017 20:21
  • Gracias por el apoyo Williams, el detalles aqui es que se esta nombrado NombreTablas con el nombre completo de las tablas de los movimientos... ADA_MOV1, pero ese registro ya lo tengo en otra tabla en donde solo viene las tres primeras letras de derecha a izquierda en este caso ADA y entonces realizar el select pero ya con la tabla completa ADA_MOV1 porque si tengo 10 unidades de negocio tendria que hacerlo como me dijiste pero estoy haciendo Select con el parametro completo ADA_MOV1 no con las primes iniciales, no se si me explico, no hay una manera que cuando yo haga un select de la tabla Unidad de Negocio y entonces concatenar el nombre de la tabla con el _MOV1 y asi hacer un select con el parametro completo ADA_MOV1?.... porque el contador debe poner solo los tres primeros digitos de la unidad de negocio...

    Nuevamente Gracias William he aprendido cosas nuevas con lo que m explicaste... quiza lo estoy interpretando mal.... y por eso no obtengo resultados...


    _ José Ángel Salinas Paz

    martes, 24 de enero de 2017 21:46
  • JA Salinas,

    Puedes cambiar el valor escrito en la columna [NombreTabla] para que contenga el mismo formato contra lo que deseas comparar, no veo donde tienes la complicación.

    Sin embargo, si sólo comparas por las tres primeras letras, ¿cómo haces en el caso de las tablas [ASA_MOV1] y [ASA_MOV2]? ¿a cuál haces referencia?


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    sábado, 28 de enero de 2017 2:15
  • Hola estaba de viaje de trabajo y no pude contestarte, ahi esta el asunto eso es precisamente lo que quiero hacer por ejemplo el parametro es dame tu unidad de negocio, el contador pone W11 entonces lo que yo quiero hacer es algo como esto...

    UnidadNegocio = W11

    Select dato1, dato2, dato3 from UnidadNegocio + _MOV1 Where ...

    Me explico, necesito concatenar la unidad de negocio con el nombre de la tabla...

    Gracias por tu tiempo ... y por tu apoyo espero tu pronta rspuesta...


    _ José Ángel Salinas Paz

    martes, 31 de enero de 2017 22:34
  • JA Salinas,

    Para nombrar un objeto concatenando una variable a un literal debes utilizar sql dinámico, es decir, debes contener dentro de una cadena una consulta sql válida y luego ejecutarla mediante el procedimiento sp_executesql. Algo que debes tomar en cuenta cuando escribes consultas dinámicas es parametrizar la consulta para evitar la inyección de código malicioso, por ejemplo:

    /*Escribir consulta dinámica*/
    DECLARE @UnidadNegocio nvarchar(4000) = N'W11';
    DECLARE @Tabla sysname = 'dbo.' + QUOTENAME(@UnidadNegocio + '_MOV1');
    DECLARE @ConsultaSQL nvarchar(4000) = 
        N'SELECT Col1, Col2 FROM ' + @Tabla + ' WHERE Col1 = @Col1';
    
    /*Ejecutar consulta*/
    DECLARE @Valor varchar(100) = 'SomeValue';
    EXECUTE sp_executesql @ConsultaSQL, N'@Col1 varchar(10)', @Valor


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 1 de febrero de 2017 15:04