none
Problemas de formato ANSI en fechas Sql Server 2008 Standard RRS feed

  • Pregunta

  • Saludos,

    Mi problema es que tengo dos servidores sql server 2008  (version 10.0.2531 y server collation Moderm_Spanish_CI_AS)  en teoria configurados de la misma forma, sin embargo una misma instrucción SQL Server me devuelve dos resultados diferentes. La instrucción es la siguiente

      DECLARE @FechaAplicaPlan DATETIME
      DECLARE @CuandoAplicar DATETIME
      DECLARE @Mes INT
      
      SET @CuandoAplicar = '20100301'
      SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar )
      SET  @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(12), DATEADD(Month, @Mes, getdate()),102),9,2,'01')as datetime))
      IF @CuandoAplicar=@FechaAplicaPlan
       PRINT 'IGUALES'
      ELSE
       PRINT 'DIFERENTES'
      PRINT @FechaAplicaPlan
      PRINT @CuandoAplicar

    En el servidor #1 el resultado es siguiente

    IGUALES
    Mar  1 2010 12:00AM
    Mar  1 2010 12:00AM

    En el servidor #2 el resultado es siguiente

    DIFERENTES
    Ene  3 2010 12:00AM
    Mar  1 2010 12:00AM

    A que se debe la diferencia si se supone que usando el standarth ANSI no debería haber este tipo de conflictos.

    Gracias

    Atte,

    German G 

     

     

    viernes, 19 de marzo de 2010 18:22

Respuestas

  • Recuerda que tienes intercalacion tambien a nivel de base de datos, y que la forma en que SQL Server interpreta las constantes de fecha puede sobre-escribirse con el lenguaje por defecto asociado al login que se conecta, o usando SET LANGUAGE o SET DATEFORMAT.

    Ejemplo (Reproducir el problema):

    SET LANGUAGE spanish;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET  @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(12), DATEADD(Month, @Mes, getdate()),102),9,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO
    SET LANGUAGE us_english;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET  @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(12), DATEADD(Month, @Mes, getdate()),102),9,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO

    Como indico Alberto, debes usar un formato que no sea dependiente del lenguaje en uso durante la ejecucion. Si la constante no contiene parte de tiempo, puedes usar el formato ISO (estilo 112 en la funcion CONVERT), de lo contrario puedes usar formato ISO8601 (estilo 126).

    Ejemplo (corregir el problema):

    SET LANGUAGE spanish;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(8), DATEADD(Month, @Mes, getdate()),112),7,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO
    SET LANGUAGE us_english;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(8), DATEADD(Month, @Mes, getdate()),112),7,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO

     

    AMB

    viernes, 19 de marzo de 2010 19:00

Todas las respuestas

  • Hola.

    Los servidores han de tener alguna diferencia en cuanto a configuración regional o el idioma de la base de datos. Yo no usaría el formato 102, sino el 112 para realizar esta operación, ya que ese formato (yyyyMMdd) siempre es entendido correctamente. Sería así:

    DECLARE @FechaAplicaPlan DATETIME
      DECLARE @CuandoAplicar DATETIME
      DECLARE @Mes INT
      
      SET @CuandoAplicar = '20100301'
      SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar ) 
      SET  @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(12), DATEADD(Month, @Mes, getdate()),112),7,2,'01')as datetime))
      IF @CuandoAplicar=@FechaAplicaPlan 
       PRINT 'IGUALES'
      ELSE
       PRINT 'DIFERENTES'
      PRINT @FechaAplicaPlan
      PRINT @CuandoAplicar

     

    No tengo un servidor donde me salgan "diferentes" con el código antiguo. Si no te funciona, nos dices.

     

     

     


    Alberto López Grande (Visita mi blog en http://qwalgrande.blogspot.es/)
    viernes, 19 de marzo de 2010 18:39
    Moderador
  • Recuerda que tienes intercalacion tambien a nivel de base de datos, y que la forma en que SQL Server interpreta las constantes de fecha puede sobre-escribirse con el lenguaje por defecto asociado al login que se conecta, o usando SET LANGUAGE o SET DATEFORMAT.

    Ejemplo (Reproducir el problema):

    SET LANGUAGE spanish;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET  @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(12), DATEADD(Month, @Mes, getdate()),102),9,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO
    SET LANGUAGE us_english;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET  @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(12), DATEADD(Month, @Mes, getdate()),102),9,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO

    Como indico Alberto, debes usar un formato que no sea dependiente del lenguaje en uso durante la ejecucion. Si la constante no contiene parte de tiempo, puedes usar el formato ISO (estilo 112 en la funcion CONVERT), de lo contrario puedes usar formato ISO8601 (estilo 126).

    Ejemplo (corregir el problema):

    SET LANGUAGE spanish;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(8), DATEADD(Month, @Mes, getdate()),112),7,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO
    SET LANGUAGE us_english;
    GO
    DECLARE @FechaAplicaPlan DATETIME
    DECLARE @CuandoAplicar DATETIME
    DECLARE @Mes INT
    
    SET @CuandoAplicar = '20100301';
    SET @Mes = DATEDIFF ( Month , getdate() , @CuandoAplicar );
    SET @FechaAplicaPlan=(SELECT cast(stuff(CONVERT(char(8), DATEADD(Month, @Mes, getdate()),112),7,2,'01')as datetime));
    
    SELECT @CuandoAplicar, @FechaAplicaPlan;
    GO

     

    AMB

    viernes, 19 de marzo de 2010 19:00
  • Saludos,

    Gracias por la información me ha sido muy util, entonces a mi entender el formato ANSI no es independiente del lenguaje ?

    viernes, 19 de marzo de 2010 20:48
  • Hola.

    No. Si quieres usar un formato de fecha que no dependa del lenguaje, usa "yyyyMMdd".

     


    Alberto López Grande (Visita mi blog en http://qwalgrande.blogspot.es/)
    viernes, 19 de marzo de 2010 21:13
    Moderador