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

datetime vs smalldatetime no SQL Server:Qual é a diferença?


Este artigo explora as principais diferenças entre o datetime e pequena data e hora tipos de dados no SQL Server.

Ambos os tipos de dados são usados ​​para armazenar valores de data e hora, no entanto, existem diferenças entre os dois. Na maioria dos casos, é melhor evitar os dois tipos e usar datetime2 em vez disso (a Microsoft também recomenda isso). De qualquer forma, aqui está uma comparação desses dois tipos de dados.



A tabela a seguir descreve algumas semelhanças e diferenças importantes entre esses dois tipos de dados.
Recurso smalldatetime datahora
Compatível com SQL (ANSI e ISO 8601) Não Não
Período 1900-01-01 a 2079-06-06 1753-01-01 a 9999-12-31
Intervalo de tempo 00:00:00 até 23:59:59 00:00:00 até 23:59:59.997
Comprimento do caractere máximo de 19 posições mínimo de 19 posições
máximo de 23
Tamanho do armazenamento 4 bytes, fixo 8 bytes, fixo
Precisão Um minuto Arredondado para incrementos de 0,000, 0,003 ou 0,007 segundos
Precisão de segundo fracionário Não Sim
Precisão de segundo fracionário definida pelo usuário Não Não
Deslocamento de fuso horário Nenhum Nenhum
Reconhecimento e preservação de deslocamento de fuso horário Não Não
Conhece o horário de verão Não Não

Devo usar 'datetime' ou 'smalldatetime'?


A Microsoft não recomenda usar esses dois tipos de dados para novos trabalhos. Você só deve usá-los se tiver uma forte razão para isso.

Mas se você tivesse que escolher, sua decisão provavelmente seria tomada pela precisão e exatidão extras de datetime versus os requisitos de armazenamento mais baixos de smalldatetime .

Em outras palavras, se você não precisa de precisão para os segundos, smalldatetime fará o trabalho usando apenas metade do espaço de armazenamento. Por outro lado, se você precisar de precisão nos segundos (ou mesmo alguns segundos fracionários), precisará usar datetime .

De qualquer forma, a Microsoft recomenda usar data , hora , datahora2 , ou deslocamento de data e hora para novos trabalhos.

Consulte pequena data e hora vs datetime2 e datahora vs datetime2 para ver como cada um desses tipos se compara a datetime2 .

Exemplo 1 – Comparação básica


Aqui está um exemplo rápido para demonstrar a diferença básica entre datetime e pequena data e hora .
DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.555';
SET @thesmalldatetime = @thedatetime;
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:
+-------------------------+---------------------+
| datetime                | smalldatetime       |
|-------------------------+---------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 |
+-------------------------+---------------------+

Aqui, defino uma pequena data e hora variável para o mesmo valor que datetime variável. Isso faz com que o valor seja convertido em smalldatetime e podemos então usar um SELECT instrução para ver o valor real que foi atribuído a cada variável.

Nesse caso, ambas as variáveis ​​arredondam o valor. Mas eles são arredondados de forma diferente.

O datahora variável arredonda a parte dos segundos fracionários. Isso ocorre porque datetime sempre arredonda para incrementos de 0,000, 0,003 ou 0,007 segundos.

O pequeno datetime variável, por outro lado, arredonda os minutos papel. Não só isso, a parte dos segundos é definida como zero. Isso é esperado, porque a documentação oficial da Microsoft afirma que smalldatetime O horário de 's é … baseado em um dia de 24 horas, com segundos sempre zero (:00) e sem segundos fracionários .

Assim, podemos ver que o datetime type fornece um valor de data/hora mais preciso e preciso.

Exemplo 2 – Definindo valores de literais de string


Nos exemplos anteriores, o smalldatime o valor foi atribuído definindo-o com o mesmo valor que datetime valor. Quando fazemos isso, o SQL Server realiza uma conversão implícita para que os dados “se ajustem” ao novo tipo de dados.

Acontece que também podemos definir o smalldatetime variável para o mesmo literal de string que inclui segundos fracionários (mesmo que esse tipo de dados não armazene segundos fracionários).

Aqui está um exemplo onde eu faço exatamente isso:
DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.555';
SET @thesmalldatetime = '2025-05-21 10:15:30.555';
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:
+-------------------------+---------------------+
| datetime                | smalldatetime       |
|-------------------------+---------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 |
+-------------------------+---------------------+

Claro, o resultado é o mesmo quando selecionamos os valores – o smalldatetime value não mostra nenhum segundo fracionário, os segundos são zero e os minutos são arredondados para cima.

No entanto, se usarmos mais de 3 casas decimais, ambos os tipos de dados retornarão um erro.

Erro para datetime :
DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.5555';
SET @thesmalldatetime = '2025-05-21 10:15:30.5555';
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:
Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string.

Erro para smalldatetime :
DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.5555';
SET @thesmalldatetime = '2025-05-21 10:15:30.5555';
SELECT 
  @thedatetime AS 'datetime',
  @thesmalldatetime AS 'smalldatetime';

Resultado:
Msg 295, Level 16, State 3, Line 5
Conversion failed when converting character string to smalldatetime data type.

Exemplo 3 - Tamanho de armazenamento


O pequeno datetime tipo de dados tem um tamanho de armazenamento fixo de 4 bytes. Este é um dos poucos benefícios smalldatetime tem mais de datetime , que tem um tamanho de armazenamento fixo de 8 bytes.

Podemos verificar o tamanho do armazenamento usando o DATALENGTH() função para retornar o número de bytes usados ​​para cada um dos nossos valores:
DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thesmalldatetime = @thedatetime;
SELECT 
  DATALENGTH(@thedatetime) AS 'datetime',
  DATALENGTH(@thesmalldatetime) AS 'smalldatetime';

Resultado
+------------+-----------------+
| datetime   | smalldatetime   |
|------------+-----------------|
| 8          | 4               |
+------------+-----------------+

Também obtemos o mesmo resultado mesmo se os convertermos em varbinary , que é mais representativo de como eles são realmente armazenados no banco de dados:
DECLARE 
  @thedatetime datetime, 
  @thesmalldatetime smalldatetime;
SET @thedatetime = '2025-05-21 10:15:30.123';
SET @thesmalldatetime = @thedatetime;
SELECT 
  DATALENGTH(CAST(@thedatetime AS varbinary(10))) AS 'datetime',
  DATALENGTH(CAST(@thesmalldatetime AS varbinary(10))) AS 'smalldatetime';

Resultado
+------------+-----------------+
| datetime   | smalldatetime   |
|------------+-----------------|
| 8          | 4               |
+------------+-----------------+