Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Como o SQL Server decide o formato para conversão implícita de data e hora?


Isso pode depender de vários fatores - configurações regionais do sistema operacional, idioma do usuário atual e configurações de formato de data. Por padrão, o Windows usa US English , e as configurações do usuário são US English e MDY .

Mas aqui estão alguns exemplos para mostrar como isso pode mudar.

O usuário está usando as configurações de idioma BRITÂNICO:
-- works:
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO

(Erro)

O usuário está usando Français:
-- works:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO

(Erro)

O usuário está novamente usando o Français:
SET LANGUAGE FRENCH;

-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe):
SELECT CONVERT(DATETIME, '2012-04-30');
GO

(Erro)

O usuário está usando DMY em vez de MDY:
SET LANGUAGE ENGLISH;
SET DATEFORMAT DMY;

-- works:
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');

-- fails:
SELECT CONVERT(DATETIME, '04-30-2012');
GO

(Erro)

Sua melhor aposta, sempre, é usar formatos de data padrão ISO, não regionais, seguros e inequívocos. Os dois que normalmente recomendo são:
YYYYMMDD                  - for date only.
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important.

Nenhum destes falha:
SET DATEFORMAT MDY;
SET LANGUAGE ENGLISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');

Portanto, recomendo fortemente que, em vez de permitir que os usuários digitem formatos de data de texto livre (ou que você mesmo use formatos não confiáveis), controle suas strings de entrada e certifique-se de que elas sigam um desses formatos seguros. Então, não importa quais configurações o usuário tenha ou quais sejam as configurações regionais subjacentes, suas datas sempre serão interpretadas como as datas que deveriam ser. Se você estiver permitindo que os usuários insiram datas em um campo de texto em um formulário, pare de fazer isso e implemente um controle de calendário ou pelo menos uma lista de seleção para que você possa controlar o formato de string que é passado de volta ao SQL Server.

Para mais informações, leia o " de Tibor Karaszi tipos de dados" e minha postagem "Bad Hábitos a serem eliminados:tratamento incorreto de consultas de data/intervalo."