Inserção do SQL Server em - como identificar a coluna que está causando erro de truncamento

11

Eu tenho um procedimento armazenado que insere 650 campos em uma tabela. A inserção está falhando com um erro de truncamento.

É um simples

INSERT INTO
SELECT (a bunch of fields) 
FROM (a bunch of tables)

Abaixo está a mensagem de erro:

A mensagem 8152, nível 16, estado 14, procedimento DSP_Procedure, linha 1075 String ou dados binários seria truncada.

Existe uma maneira rápida de identificar qual campo está causando o erro de truncamento?

O fato de a instrução select a ser inserida na tabela ter 650 campos dificulta a identificação de qual campo está causando o erro de truncamento.

Talvez eu possa comentar blocos de campos de cada vez para que o SP insira apenas 100 campos por vez e execute o SP 6 ou 7 vezes diferentes até que eu possa pelo menos diminuir para um grupo de 100 campos que conterá o campo que está causando o erro de truncamento.

Como alternativa, estou pensando que talvez eu possa apenas SELECT INTOuma nova tabela e, em seguida, compare os comprimentos de dados na tabela versus os comprimentos de dados da tabela de destino que estou tentando inserir no meu SP para ver qual campo contém um comprimento maior que o esperado. ..

Estou usando o SQL Server 2014.

Alguma alternativa mais fácil?

Juan Velez
fonte
11
Gostaria de ir para Information_SCHEMA.COLUMNS e comparar os tipos de dados com os que você está tentando inserir. Infelizmente, o SQL Server não possui tipos de dados dinâmicos para declaração de variáveis, como o ORACLE.
MguerraTorres
2
Gostaria de usar sua segunda opção, inserir em uma nova tabela (ou #temp) e comparar os comprimentos das colunas. Ou você pode envolver LEN () em torno de todas as colunas no select e fazer com que uma consulta externa faça um MAX () para cada ... que daria o maior tamanho de texto para os campos. Obviamente, isso pressupõe que é um campo char que está causando problemas. Não está usando smalldatetime ou tinyint?
Jonathan Fite
11
Eu iria com a abordagem "Selecionar em" e compararia os comprimentos das colunas, sim. Talvez com "WHERE 1 = 0" para que a tabela não tenha linhas. Inábil se o seu SELECT não incluir nomes exclusivos para as colunas selecionadas. Eu formato listas longas de colunas como uma linha de script por coluna, depois o nome da coluna "AS" na próxima linha, se necessário, e uma linha em branco após quatro colunas para facilitar a manutenção da lista. Isso também suporta a seleção de muitas linhas e a execução de Ctrl + K Ctrl + C para alterá-las para comentários, para que você possa atacar a operação Inserir dessa maneira, mas as colunas deixadas de fora teriam que ser anuláveis.
Robert Carnegie

Respostas:

9

Infelizmente, você encontrou um "recurso" bastante antigo . Existe um tíquete do Connect aberto desde 2008 e, por quase dez anos, isso não foi significativo o suficiente para justificar uma correção.

A solução padrão é, como você imaginou, select into...seguida pela comparação dos metadados da tabela. Outra possibilidade é a busca binária na coluna incorreta, mas isso também é trabalho manual. Existem alguns hacks para comparação de metadados, mas não existe uma solução simples e elegante. Talvez algumas ferramentas de terceiros ajudem, mas não estou ciente disso.

vonPryz
fonte
1

O uso do (QUERYTRACEON 460) não funcionou para mim ao colocá-lo no final da minha consulta.

Eu o liguei no nível do banco de dados e funcionou:

DBCC TRACEON(460, -1);
GO

Porém, certifique-se de desativá-lo depois de encontrar e corrigir o problema, não o deixe ligado!

DBCC TRACEOFF(460, -1);
GO
Taylor Brown
fonte