SQL Server Inserisci in - Come identificare la colonna che causa l'errore di troncamento


11

Ho una procedura memorizzata che inserisce 650 campi in una tabella. L'inserimento non riesce con un errore di troncamento.

È semplice

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

Di seguito è riportato il messaggio di errore:

Messaggio 8152, livello 16, stato 14, procedura DSP_Procedure, riga 1075 I dati stringa o binari verrebbero troncati.

Esiste un modo rapido per identificare quale campo sta causando l'errore di troncamento?

Il fatto che l'istruzione select da inserire nella tabella abbia 650 campi rende difficile individuare quale campo sta causando l'errore di troncamento.

Sto pensando che posso forse commentare blocchi di campi alla volta in modo da far inserire solo SP 100 campi alla volta e quindi eseguire SP 6 o 7 volte diverse fino a quando posso almeno restringere il campo a un gruppo di 100 campi che conterrà il campo che causa l'errore di troncamento.

In alternativa, sto pensando che forse posso solo SELECT INTOuna nuova tabella e quindi confrontare le lunghezze dei dati nella tabella con le lunghezze dei dati della tabella di destinazione che sto cercando di inserire nel mio SP per vedere quale campo contiene una lunghezza del campo più lunga del previsto. ..

Sto usando SQL Server 2014.

Qualche alternativa più semplice?


1
Andrei su INFORMATION_SCHEMA.COLUMNS e confronterei i tipi di dati con quelli che stai cercando di inserire. Sfortunatamente il server SQL non ha tipi di dati dinamici per la dichiarazione delle variabili come ORACLE.
MguerraTorres,

2
Vorrei usare la tua seconda opzione, inserirla in una nuova (o #temp) tabella e quindi confrontare le lunghezze delle colonne. Oppure potresti avvolgere LEN () attorno a tutte le colonne nella selezione e quindi fare in modo che una query esterna faccia un MAX () per ciascuno ... che ti darebbe la lunghezza del testo più grande per i campi. Ovviamente, ciò presuppone che sia un campo char che ti sta dando problemi. Non usi smalldatetime o tinyint?
Jonathan Fite,

1
Vorrei andare con l'approccio "Seleziona in" e confrontare le lunghezze delle colonne, sì. Forse con "WHERE 1 = 0" in modo che la tabella non abbia righe. Imbarazzante se il tuo SELECT non include nomi univoci per le colonne selezionate. Formatto gli elenchi di colonne lunghe come una riga di script per colonna, quindi il nome della colonna "AS" sulla riga successiva, se necessario, e una riga vuota dopo quattro colonne per semplificare il posizionamento nell'elenco. Ciò supporta anche la selezione di molte righe e l'esecuzione di Ctrl + K Ctrl + C per modificarle in commenti, in modo da poter attaccare l'operazione Inserisci in quel modo, ma le colonne lasciate fuori dovrebbero essere nullable.
Robert Carnegie,

Risposte:



9

Sfortunatamente, hai riscontrato una "caratteristica" piuttosto vecchia . Esiste un biglietto Connect aperto dal 2008 e per quasi dieci anni non è stato abbastanza significativo da giustificare una soluzione.

La soluzione standard è, come hai immaginato, select into...seguita dal confronto dei metadati della tabella. Un'altra possibilità è la ricerca binaria nella colonna offensiva, ma è anche un lavoro manuale. Esistono alcuni hack per il confronto dei metadati, ma non esiste una soluzione semplice ed elegante. Forse alcuni strumenti di terze parti sarebbero di aiuto, ma non ne sono consapevole.


1

L'uso di (QUERYTRACEON 460) non ha funzionato per me quando è stato inserito alla fine della mia query.

L'ho attivato a livello di DB e ha funzionato:

DBCC TRACEON(460, -1);
GO

Assicurati di disattivarlo una volta trovato e risolto il problema, non lasciarlo acceso!

DBCC TRACEOFF(460, -1);
GO
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.