none
¿Error al crear un store procedure con rango de fechas? RRS feed

  • Pregunta

  • tengo una consulta:

    Me genera error al crear mi store procedure cuando le paso un rango de fechas.Sin embargo si solo le paso el id de proyecto funciona bien, el problema es cuando al where le paso un rango de fechas

    CREATE PROCEDURE [dbo].[PA_Control_horas_Proyecto]
    @IdProyecto varchar(6),@Fecha1 date, @Fecha2 date
    
    /*
        EXEC [PA_Control_horas_Proyecto] '103569','15-09-2019','15-10-2019'
    */
    ------------------------------------------------------------------------------
    ------------------------------------------------------------------------------
    as
    begin
    IF @Fecha1 is null 
       or @Fecha2 is null 
       or @Fecha1 > @Fecha2
      return -1;
    DECLARE @SQLDynamic NVARCHAR(MAX)-- STRING QUE CONTENDRA TODO
    --DECLARE @FinalDate NVARCHAR(50)=right(@MesAño,4)+'-'+'01-'+left(@MesAño,2)-- creamos el año + el mes + el primer dia
    
    --obtiene el primer dia del mes
    ;with CTE_DAY_Recursive as (
    SELECT @Fecha1 as DayDINAMIC 
    union all
    SELECT dateadd (day, +1, DayDINAMIC)   
      from CTE_DAY_Recursive
      where DayDINAMIC < @Fecha2
    )
    SELECT  @SQLDynamic=COALESCE(@SQLDynamic+',','')+'['+CAST(DayDINAMIC    AS nvarchar(20))+']' 
    FROM CTE_DAY_Recursive  --Obtenemos los registros 
    
    DECLARE @SQLFULL NVARCHAR(MAX)='
    
    select * from
    (
    select 
        Id_Colaborador as ''DNI'',
        Nombre_Colaborador as ''COLABORADOR'',
        dbo.FU_Desc_Proyecto(Id_Unidad_Organizativa) as ''PROYECTO UO'',
        Nro_Proyecto_Registro +'' ''+Descripcion_Proyecto_Registro as ''PROYECTO ASIGNADO'',
        Fecha_Registro,
        sum(Hora_Registro) as ''Hora_Registro''
        from Sigeri
        where Nro_Proyecto_Registro = '+@IdProyecto+' and Fecha_Registro>='+@Fecha1+' and Fecha_Registro<='+@Fecha2+'
        group by Id_Colaborador,Nombre_Colaborador,Id_Unidad_Organizativa,Nro_Proyecto_Registro,Fecha_Registro,Descripcion_Proyecto_Registro
    )s
    pivot(
        max(Hora_Registro)
        for[Fecha_Registro] in --(select Fecha_Registro FROM Sigeri)
    ('+@SQLDynamic+') --Le pasamos los registros
    )p'
    
    
    EXEC(@SQLFULL)
    end

    He probado sin el rango de fechas y funciona a la perfección.Además de ello uso pivot para convertir las fechas en columnas.

    El mensaje de error que me muestra es el siguiente

    Los tipos de datos varchar y date son incompatibles con el operador add.

    miércoles, 6 de noviembre de 2019 16:54

Todas las respuestas

  • Prueba de esta forma

    CREATE PROCEDURE [dbo].[PA_Control_horas_Proyecto]
    @IdProyecto varchar(6),@Fecha1 NVARCHAR(20), @Fecha2  NVARCHAR(20)
    
    /*
        EXEC [PA_Control_horas_Proyecto] '103569','15-09-2019','15-10-2019'
    */
    ------------------------------------------------------------------------------
    ------------------------------------------------------------------------------
    as
    begin
    IF @Fecha1 is null 
       or @Fecha2 is null 
       or @Fecha1 > @Fecha2
      return -1;
    DECLARE @SQLDynamic NVARCHAR(MAX)-- STRING QUE CONTENDRA TODO
    --DECLARE @FinalDate NVARCHAR(50)=right(@MesAño,4)+'-'+'01-'+left(@MesAño,2)-- creamos el año + el mes + el primer dia
    
    --obtiene el primer dia del mes
    ;with CTE_DAY_Recursive as (
    SELECT @Fecha1 as DayDINAMIC 
    union all
    SELECT dateadd (day, +1, DayDINAMIC)   
      from CTE_DAY_Recursive
      where DayDINAMIC < @Fecha2
    )
    SELECT  @SQLDynamic=COALESCE(@SQLDynamic+',','')+'['+CAST(DayDINAMIC    AS nvarchar(20))+']' 
    FROM CTE_DAY_Recursive  --Obtenemos los registros 
    
    DECLARE @SQLFULL NVARCHAR(MAX)='
    
    select * from
    (
    select 
        Id_Colaborador as ''DNI'',
        Nombre_Colaborador as ''COLABORADOR'',
        dbo.FU_Desc_Proyecto(Id_Unidad_Organizativa) as ''PROYECTO UO'',
        Nro_Proyecto_Registro +'' ''+Descripcion_Proyecto_Registro as ''PROYECTO ASIGNADO'',
        Fecha_Registro,
        sum(Hora_Registro) as ''Hora_Registro''
        from Sigeri
        where Nro_Proyecto_Registro = '+''''+ @IdProyecto +''''+ 'and Fecha_Registro>=CONVERT(DATETIME,'+''''+ @Fecha1 +''''+',102) and Fecha_Registro<=CONVERT(DATETIME,'+''''+ @Fecha2 +''''+',102)
        group by Id_Colaborador,Nombre_Colaborador,Id_Unidad_Organizativa,Nro_Proyecto_Registro,Fecha_Registro,Descripcion_Proyecto_Registro
    )s
    pivot(
        max(Hora_Registro)
        for[Fecha_Registro] in --(select Fecha_Registro FROM Sigeri)
    ('+@SQLDynamic+') --Le pasamos los registros
    )p'
    
    
    EXEC(@SQLFULL)
    end


    Damian C M

    miércoles, 6 de noviembre de 2019 17:08
  • Me muestra el mismo error, parece que la cadena @SQLFULL NVARCHAR(MAX) no admite date, además tener en cuenta que el campo Fecha_Registro es date. Mire en otra pagina quizás esto tengas de referencia https://rstopup.com/los-tipos-de-datos-varcharmax-y-la-fecha-son-incompatibles-en-el-complemento-operador.html



    • Editado DUM28 miércoles, 6 de noviembre de 2019 17:21
    miércoles, 6 de noviembre de 2019 17:13
  • Los tipos de datos varchar y date son incompatibles con el operador add.

    Básicamente ese mensaje te está diciendo que no puedes hacer 'texto'+@fecha en una sentencia SQL. Si estás acostumbrado a otros lenguajes de programación, esperas que al hacer eso la fecha se convierta en cadena de texto y se concatene con el otro texto. Pero en SQL tienes que escribir explícitamente la conversión:

    '... lo que sea ...''' + CONVERT(varchar(20), @laFecha, 112) + '''... lo que sea ...'

    Observa las comillas que encierran la fecha. Son necesarias.

    Lo ideal para no tener que hacer todo esto es evitar el sql dinamico y parametrizar la sentencia, en cuyo caso no se necesitan comillas ni concatenacion. O bien si no hay mas remedio que usar el SQL dinamico, entonces en lugar de EXEC usar sp_executesql, que permite aplicar parametros en el SQL dinamico.

     
    miércoles, 6 de noviembre de 2019 17:20
  • como seria la ejecución con sp_executesql ya que no puedo cambiar ese sql dinámico
    miércoles, 6 de noviembre de 2019 17:27
  • La solución que encontré fue pasarle triple comilla simple
    miércoles, 6 de noviembre de 2019 17:46
  • La solución que encontré fue pasarle triple comilla simple

    Sí, lo de la triple comilla simple es precisamente lo que yo te escribí en el ejemplo que te puse y que te recalqué al escribir "Observa las comillas que encierran la fecha. Son necesarias." 

    En cuanto a lo de cómo se utiliza el sp_executesql, fíjate en la documentación:

    https://docs.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql?view=sql-server-ver15

    y baja hasta donde está el "Ejemplo A" que precisamente usa un parámetro.

    miércoles, 6 de noviembre de 2019 19:10