Estou recebendo este erro:
Erro ao converter o tipo de dados nvarchar para bigint
Quando tento executar a consulta abaixo, se eu remover a condição de comparação de datas, funciona perfeitamente.
select c.reference AccountNo,
i.insurance_cancellation_dt CustomerCancelDte,
cus.ext_name CustomerName,
case when f.amt_matched=0 then 'Paid' else 'Unpaid' end ChargebackStatus,
'' DlrCancelRequiredInd,
acf.reference NetcheckAccountNo,
iType.value ProductDesc,
acf.amount TotRefundAmt,
iParty.ext_name VendorName,
v.vin_no Vin
from
contract c
inner join
asset_hdr ah on c.contract_id = ah.current_contract_id
and c.dealer_id = 1201
and c.reference = '100981'
inner join
asset_hdr_insurance i on i.asset_hdr_id = ah.asset_hdr_id
-- and i.insurance_cancellation_dt > '2025-01-01'
-- and i.insurance_cancellation_dt < '2025-04-01'
inner join
party cus on cus.party_id = c.cparty_id
inner join
asset_custom_flow acf on acf.reference = i.asset_hdr_insurance_id
and acf.custom_flow_hdr_id = (select custom_flow_hdr_id
from custom_flow_hdr
where name = 'AMP Chargeback')
inner join
flow f on f.contract_id = c.contract_id
and f.custom_flow_link_no = acf.link_no
inner join
xt_lookupset iStatus on iStatus.xt_lookupset_id = i.insurance_status
inner join
xt_lookupset iType on iType.xt_lookupset_id = i.insurance_type
inner join
party iParty on iParty.party_id = i.insurance_party_id
inner join
asset_class_vehicle v on v.asset_hdr_id = ah.asset_hdr_id
and v.vin_no = 'TTXJG330ML5P34985'
Isso parece um problema de esquema, onde o
insurance_cancellation_dt
é definido incorretamente como um int grande.Com isso em mente, a melhor solução é consertar os dados (porque o que você realmente tem seria considerado quebrado ). Mas entendo que isso nem sempre é possível em um sistema existente.
Com isso em mente, não posso ter certeza da solução exata sem ver uma amostra de como são os dados reais, mas imagino que as linhas comentadas provavelmente se pareçam mais com isto:
Observe a mudança no operador para a primeira expressão de desigualdade. O operador original parecia errado e provavelmente deveria ser usado
>=
em vez de>
(mas o operador<
rather than<=
provavelmente está correto).Além disso, vejo isto:
Não acho que essa seja a causa do seu erro, e normalmente eu o consideraria normal, mas como potencialmente temos outras situações de incompatibilidade de tipos na consulta, pode haver algo aqui que valha a pena abordar. Se
c.reference
for, na verdade, um tipo numérico de algum tipo, em vez de um tipo string/varchar, as regras de precedência de tipos do SQL Server podem exigir a conversão de TODOS osc.reference
valores para varchar, em vez de converter'100981'
para o tipo numérico uma vez. Seria necessário fazer isso para cada linha , mesmo para valores que não correspondam à expressão... porque, de que outra forma, saberia se o valor correspondeu ou não? Pior ainda, isso impede o uso de qualquer índice que você possa ter para esta coluna.Agora temos esta nova informação:
É estranho que a remoção de expressões condicionais resolva o problema (daí: uma postagem no Stack Overflow 😉). Se houvesse um problema de conversão de tipo em outro lugar, mais expressões condicionais tenderiam a reduzir o tamanho do conjunto de resultados, o que poderia ajudar a evitar o erro, enquanto a remoção de uma expressão tenderia a adicionar linhas e, portanto, aumentar a chance de erro. Isso faz o oposto.
Ainda assim: o otimizador de consultas pode fazer coisas estranhas. Por exemplo, adicionar uma expressão pode levar a percorrer um índice estreito em vez de buscar em uma tabela mais ampla, ou vice-versa. Dessa forma, adicionar a expressão pode significar que você visualiza mais linhas, mas tem menos leituras de página. Há outros motivos pelos quais isso também pode gerar resultados estranhos.
O certo é que, em algum lugar, isso está causando uma conversão de um tipo de dado (
nvarchar
) para outro (bigint
) que você não pretendia. Prestar mais atenção aos tipos de dados de coluna e literais permitirá que você evite isso.Vale ressaltar também que não há literais "
nvarchar
oubigint
" em nenhuma parte da consulta.nvarchar
precisaria de umN
prefixo, e não há nada numérico grande o suficiente parabigint
. Também não há operações de conversão naSELECT
cláusula. Portanto, DEVE ser uma conversão ocorrendo dentro de uma expressão condicional entre duas colunas em uma cláusula "ON
ouWHERE
". Eu prestaria mais atenção a estas três expressões:Onde for possível, uma das colunas
insurance_status
,insurance_type
, ouacf.reference
contém principalmente strings que representam valores de ID nas tabelas pareadas, mas são definidas paranvarchar
também permitir uma gama mais ampla de informações de status/descritivas em algumas linhas. Lembre-se: strings que representam valores de ID não são a mesma coisa que conter os valores de ID diretamente.É muito provável que esse problema ocorra porque o SQL Server está interpretando
i.insurance_cancellation_dt
comoNVARCHAR
(string), não comoDATE
.Abaixo estão as correções:
1). Converta a coluna para
DATE
a condição :E CAST(i.insurance_cancellation_dt COMO DATA) > '2025-01-01'
E CAST(i.insurance_cancellation_dt COMO DATA) < '2025-04-01'
2): Corrigir o tipo de coluna (ideal):
Verifique o tipo de dados real de
i.insurance_cancellation_dt
:O erro fornecido parece ocorrer quando você adiciona ( e porque o servidor pode
i.insurance_cancellation_dt > '2025-01-01'
reordenar)
internamente as etapas de execução (junções, filtros) e tentar corresponder uma coluna a uma na linha (se esses tipos não corresponderem).nvarchar
bigint
acf.reference = i.asset_hdr_insurance_id
Espero que esta solução ajude!
Acho que é por causa de
c.references='100981'
. Por causa do ,''
ele será interpretado como string (nvarchar).Você já tentou isso? :