¿Cómo hago referencia a un campo en una consulta SQL dinámica?

Tengo una consulta SQL dinámica en SQL Server. Así que lo construyo, lo configuro en una variable y luego intento formatear una cláusula where basada en una fecha. Sin embargo, cuando intento hacer esto, obtengo "El identificador de varias partes 'NOMBRE DE CAMPO" no se puede vincular. Creo que esto se debe a que las tablas reales están en una dinámica de claus, por lo que no se pueden ver hasta que se compilan. ¿Alguna forma de evitar esto?

Aquí estoy tratando de decir, dame todas las Personas cuyo DOB ​​entre AÑO + MES especificado, por ejemplo, 201001 y 201012 sería el año completo de 2010. Aquí está el código en parte ...

    ALTER PROCEDURE get_persons_by_search_criteria

@month_from as nvarchar(2) = null,
@year_from as nvarchar(4) = null,
@month_to as nvarchar(2) = null,
@year_to as nvarchar(4) = null


AS

declare @from_date varchar(10)
declare @to_date varchar(10)
declare @sqlstr varchar(5000)

set @sqlstr = ' SELECT     
    Person.PersonID, 
    Person.FirstName, 
    Person.LastName, 
FROM    Person '

--Attemtping to create a value like 201108 (year + month)
set @from_date = Convert(VarChar(10), @year_from) + Replace(Str(@month_from, 2), ' ', '0')  
set @to_date = Convert(VarChar(10), @year_to) + Replace(Str(@month_to, 2), ' ', '0') 

set @sqlstr = @sqlstr +  ' WHERE '
set @sqlstr = @sqlstr + Convert(VarChar(10), Person.DOBYear) + Replace(Str(Person.DOBMonth, 2), ' ', '0') 
set @sqlstr = @sqlstr + ' BETWEEN '   + @from_date + ' and ' + @to_date


exec(@sqlstr)

preguntado el 27 de agosto de 11 a las 19:08

No parece que deba ser SQL dinámico. ¿Por qué no puedes usar esta tecnica de su pregunta anterior? -

Indique la versión de SQL Server cuando haga preguntas. La memoria de @ Martin es claramente mejor que la mía, pero no todos sabremos lo que respondió la última vez que le preguntaron "¿Qué versión de SQL Server?" -

2 Respuestas

Esta línea da el error, porque la tabla PERSON no está abierta cuando construye la cadena dinámica.

set @sqlstr = @sqlstr + Convert(VarChar(10), Person.DOBYear) + Replace(Str(Person.DOBMonth, 2), ' ', '0')

Prueba esta

set @sqlstr = @sqlstr + ' Convert(VarChar(10), Person.DOBYear) + Replace(Str(Person.DOBMonth, 2), '' '', ''0'') '

Debería hacer el truco por ti ...

Respondido 27 ago 11, 23:08

Me doy cuenta de que ya solucionó su problema y aceptó una respuesta, pero pensé que también señalaría algunas otras mejoras potenciales (tanto para usted como para los futuros lectores de la pregunta).

ALTER PROCEDURE dbo.get_persons_by_search_criteria
    @month_from VARCHAR(2) = NULL,
    @year_from  VARCHAR(4) = NULL,
    @month_to   VARCHAR(2) = NULL,
    @year_to    VARCHAR(4) = NULL
AS
BEGIN 
   SET NOCOUNT ON;

   SELECT
       PersonID, DOBYear, DOBMonth
   FROM
       dbo.Person
   WHERE 
       DOBYear + RIGHT('0' + DOBMonth, 2) + '01'
       BETWEEN @year_from + RIGHT('0' + @month_from, 2) + '01'
           AND @year_to   + RIGHT('0' + @month_to,   2) + '01'
   ORDER BY 
       PersonID, DOBYear, DOBMonth;
END
GO

¿No es eso más agradable a la vista, más fácil de seguir y más fácil de mantener?

Resumen:

Aún mejor sería simplemente almacenar su fecha de nacimiento como una FECHA en primer lugar. ¿Por qué almacenarías el año y el mes como cadenas separadas? Debe haber alguna razón por la que estás haciendo esto, pero no puedo imaginarme de qué se trata. Todo lo que hace es hacer que este tipo de coincidencia de cadenas sea menos eficiente que si estuviera usando fechas, reduce su capacidad para realizar cualquier tipo de operaciones de fecha en los valores y hace que sea muy difícil validar los valores pasados. se ahogará más tarde de lo debido si alguien llama a lo siguiente:

EXEC get_persons_by_search_criteria 
    @month_from = '97',
    @year_from  = 'Audi',
    @month_to   = 'TT',
    @year_to    = 'Oy!!';

Lo que podrían hacer, porque no realizas ninguna validación. Con las variables DATE, al menos el mensaje de error que regresa tendría sentido. Ahora mismo, con cualquiera de nuestras versiones, obtendrán un conjunto de resultados vacío.

Respondido 29 Jul 20, 21:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.