AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 71150
Accepted
Simon Hughes
Simon Hughes
Asked: 2014-07-11 01:44:12 +0800 CST2014-07-11 01:44:12 +0800 CST 2014-07-11 01:44:12 +0800 CST

Comparação SQL Datetime/datetimeoffset(2) e estranheza de elenco implícito

  • 772

Descobri um problema ao inserir dados em nosso banco de dados. Minha instrução de inserção estava verificando a existência de dados na cláusula WHERE para evitar a inserção de dados duplicados. Nenhum foi detectado e o INSERT aconteceu. No entanto, a restrição exclusiva rejeitou os dados porque já existiam no banco de dados.

O problema era que os dados a serem inseridos eram DATETIMEOFFSET(2) e o campo do banco de dados inserido era DATETIME.

Para mostrar que você quer que eu esteja falando, execute o seguinte:

DECLARE @dt  DATETIME          = '2014-07-07 09:49:33.000';
DECLARE @dto DATETIMEOFFSET(2) = '2014-07-07 09:49:33.00 +07:00';

PRINT CASE WHEN @dt = @dto THEN 'Equals matches'
           ELSE 'Equals does not match'
      END

PRINT CASE WHEN @dt = CAST(@dto AS DATETIME) THEN 'Cast matches'
           ELSE 'Cast does not match'
      END

Ele imprime:

  • Igual não corresponde
  • Transmitir partidas

O operador de comparação (=) não funciona da mesma forma que a conversão implícita se você inserir os dados. Na verdade, o operador cast/convert descarta o deslocamento! Loucura.

Por que o operador de comparação funciona de maneira diferente da conversão implícita que ocorre durante um INSERT?

sql-server
  • 2 2 respostas
  • 13784 Views

2 respostas

  • Voted
  1. Best Answer
    souplex
    2014-07-11T02:17:08+08:002014-07-11T02:17:08+08:00

    Parece que o oposto é verdadeiro: a conversão implícita leva o deslocamento para a equação, mas as funções cast/convert não.

    DECLARE @dt  DATETIME          = '2014-07-07 02:49:33.000';
    DECLARE @dto DATETIMEOFFSET(2) = '2014-07-07 09:49:33.000 +07:00';
    
    PRINT CASE WHEN @dt = @dto THEN 'Equals matches'
               ELSE 'Equals does not match'
          END
    
    PRINT CASE WHEN @dt = CAST(@dto AS DATETIME) THEN 'Cast matches'
               ELSE 'Cast does not match'
          END
    
    PRINT CASE WHEN @dt = CONVERT(DATETIME,@dto) THEN 'Convert matches'
               ELSE 'Convert does not match'
          END    
    

    A comparação (deduzidas 7 horas de @dt) resulta em:

    • Partidas iguais
    • O elenco não corresponde
    • Converter não corresponde

    Fiz mais algumas investigações e me deparei com este artigo.

    "Quando você converte de datetime2 ou datetimeoffset para date, não há arredondamento e a parte da data é extraída explicitamente. Para qualquer conversão implícita de datetimeoffset para data, hora, datetime2, datetime ou smalldatetime, a conversão é baseada na data e hora locais valor."

    Então, quando você quiser tratar '2014-07-07 09:49:33.000' e '2014-07-07 09:49:33.000 +07:00' como iguais, sua única opção é fazer uma conversão explícita via cast ou converter. Como as conversões implícitas só funcionariam quando o deslocamento do fuso horário do seu servidor fosse o mesmo que o deslocamento especificado em @dto.

    • 10
  2. andowero
    2021-04-30T22:21:51+08:002021-04-30T22:21:51+08:00

    Bem, a comparação e o CAST funcionam de maneira diferente.

    A comparação usa precedência de tipo para determinar como comparar tipos diferentes. DATETIMEOFFSETestá em 4º lugar, DATETIMEe DATETIME2em 6º e 5º lugar respectivamente. Portanto, o DATETIMEargumento é convertido (usando CAST, veja abaixo) para DATETIMEOFFSETprimeiro.

    A conversão paraDATETIMEOFFSET pode ser alcançada de três maneiras possíveis (talvez mais?):

    • CASTque adiciona fuso horário "+00:00" (UTC)
    • CONVERTque adiciona fuso horário "+00:00" (UTC)
    • AT TIMEZONEque adiciona qualquer fuso horário que você fornecer como o argumento do lado direito

    Infelizmente, nunca encontrei nenhuma documentação sobre o comportamento de CASTnem CONVERTquando "upscaling" para DATETIMEOFFSET. Portanto, esse comportamento pode diferir entre máquinas e versões.

    Por outro lado, a conversão para DATETIME corta a parte "deslocada".

    Então, no seu caso:

    @dt = @dto
      -- @dt gets converted to DATETIMEOFFSET(2)
      -- you are comparing:
      -- '2014-07-07 09:49:33.000 +00:00' = '2014-07-07 09:49:33.00 +07:00'
    
    @dt = CAST(@dto AS DATETIME)
      -- botha are DATETIME, but @dto gets "downscaled" to DATETIME
      -- you are comparing:
      -- '2014-07-07 09:49:33.000' = '2014-07-07 09:49:33.00'
    
    • 2

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve