Gibt es einen guten path zum Debuggen "String oder Binärdaten würden abgeschnitten?"

Das Jahr ist 2010.

SQL server Lizenzen sind nicht billig.

Und doch zeigt dieser Fehler immer noch nicht die Zeile oder die Spalte oder den Wert an , der das Problem verursacht hat. Hölle, es kann nicht einmal sagen, ob es sich um "String" oder "binäre" data handelt.

Bin ich etwas fehlt?

Eine schnelle und verschmutzte Art, diese zu fixieren, ist, die Zeilen so in eine neue physische Tabelle zu wählen:

SELECT * INTO dbo.MyNewTable FROM <the rest of the offending query goes here> 

… und dann das Schema dieser Tabelle mit dem Schema der Tabelle vergleichen, in die das INSERT vorher gegangen ist – und nach der größeren Spalte suchen.

Mir ist klar, dass das eine alte ist. Hier ist ein kleines Stück Code, das ich benutze, das hilft.

Was das tut, gibt eine Tabelle der max Längen in der Tabelle, die Sie aus wählen möchten, zurück. Sie können dann die Feldlängen mit dem für jede Spalte zurückgegebenen Max vergleichen und herausfinden, welche das Problem verursacht. Dann ist es einfach eine einfache Abfrage, um die data aufzuräumen oder auszuschließen.

 DECLARE @col NVARCHAR(50) DECLARE @sql NVARCHAR(MAX); CREATE TABLE ##temp (colname nvarchar(50), maxVal int) DECLARE oloop CURSOR FOR SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'SOURCETABLENAME' AND TABLE_SCHEMA='dbo' OPEN oLoop FETCH NEXT FROM oloop INTO @col; WHILE (@@FETCH_STATUS = 0) BEGIN SET @sql = ' DECLARE @val INT; SELECT @val = MAX(LEN(' + @col + ')) FROM dbo.SOURCETABLENAME; INSERT INTO ##temp ( colname, maxVal ) VALUES ( N''' + @col + ''', -- colname - nvarchar(50) @val -- maxVal - int )'; EXEC(@sql); FETCH NEXT FROM oloop INTO @col; END CLOSE oloop; DEALLOCATE oloop SELECT * FROM ##temp DROP TABLE ##temp; 

Sie können die Länge jedes eingefügten Wertes mit einer if-Bedingung überprüfen, und wenn der Wert mehr Breite als die aktuelle Spaltenbreite benötigt, schneiden Sie den Wert ab und casting einen benutzerdefinierten Fehler.

Das sollte funktionieren, wenn man nur identifizieren muss, welches das Feld das Problem verursacht. Ich weiß nicht, ob es einen besseren path gibt, dies zu tun.

Empfehlen Sie stimmen für die Erweiterungsanfrage auf Microsofts Website. Es ist seit 6 Jahren aktiv, also wer weiß, ob Microsoft jemals etwas dagegen tun wird, aber zumindest kann man ein quietschendes Rad sein: Microsoft Connect

Ein anderer path hier ist die binäre search zu verwenden.

Kommentieren Sie die Hälfte der Spalten in Ihrem Code und versuchen Sie es erneut. Wenn der Fehler weiterhin besteht, kommentiere noch eine halbe Hälfte und versuche es erneut. Sie werden Ihre search auf nur zwei Spalten am Ende eingrenzen.

Für String Trunkierung, kam ich mit der folgenden Lösung, um die maximale Längen aller Spalten zu finden:

1) Alle data in eine temporäre Tabelle auswählen (ggf. Spaltennamen eingeben)

 SELECT col1 ,col2 ,col3_4 = col3 + '-' + col4 INTO #temp; 

2) Führen Sie die folgende SQL-statement in derselben Verbindung aus (passen Sie den temporären Tabellennamen bei Bedarf an):

 DECLARE @table VARCHAR(MAX) = '#temp'; -- change this to your temp table name DECLARE @select VARCHAR(MAX) = ''; DECLARE @prefix VARCHAR(256) = 'MAX(LEN('; DECLARE @suffix VARCHAR(256) = ')) AS max_'; DECLARE @nl CHAR(2) = CHAR(13) + CHAR(10); SELECT @select = @select + @prefix + name + @suffix + name + @nl + ',' FROM tempdb.sys.columns WHERE object_id = object_id('tempdb..' + @table); SELECT @select = 'SELECT ' + @select + '0' + @nl + 'FROM ' + @table EXEC(@select); 

Es wird eine Ergebnismenge mit den Spaltennamen zurückgegeben, die mit 'max_' vorangestellt sind und die maximale Länge jeder Spalte anzeigen.

Sobald Sie die errorshafte Spalte identifiziert haben, können Sie andere ausgewählte statementen ausführen, um extra lange Zeilen zu finden und Ihren Code / data nach Bedarf anzupassen.

Ich kann nicht wirklich gut denken.
Ich habe einmal viel time damit verbracht, eine sehr informative "Division by zero" Nachricht zu debuggen.

Normalerweise kommentieren Sie verschiedene Stücke des Ausgabecodes, um das zu finden, das Probleme verursacht.
Dann nehmen Sie dieses Stück, das Sie gefunden haben und machen es einen Wert zurückgeben, der anzeigt, dass es ein Problem statt des tatsächlichen Wertes gibt (in Ihrem Fall sollte die characterfolge Ausgabe mit dem len(of the output) replace). Dann manuell vergleichen Sie mit der Länge der Spalte, die Sie es insert in.

aus der Zeilennummer in der Fehlermeldung, sollten Sie in der Lage sein, die Einfügungsabfrage zu identifizieren, die den Fehler verursacht. modifizieren Sie diese in eine select-Abfrage, um AND LEN(your_expression_or_column_here) > CONSTANT_COL_INT_LEN für die characterfolge verschiedene Spalten in Ihrer Abfrage AND LEN(your_expression_or_column_here) > CONSTANT_COL_INT_LEN . schau auf die Ausgabe und es wird dir die schlechten Zeilen geben.

Technisch gibt es keine Zeile zu zeigen, weil SQL nicht die data an die Tabelle schreiben. Ich habe in der Regel nur die Trace erfassen, führen Sie es Query Analyzer (es sei denn, das Problem ist bereits offensichtlich aus der Trace, die es in diesem Fall sein kann), und schnell Debug von dort mit der alten alten "modifizieren meine UPDATE zu einem SELECT" -Methode. Ist es nicht wirklich einfach zu einem von zwei Dingen zu brechen:

a) Ihre Spaltendefinition ist falsch, und die Breite muss geändert werden b) Ihre Spaltendefinition ist richtig, und die App muss defensiver sein

?

Das Beste, was für mich gearbeitet hat, war, die Zeilen zuerst in eine temporäre Tabelle mit select …. in # tryable Dann nahm ich die maximale Länge jeder Spalte in diesem Temp-Tabelle. z.B. wähle max (len (jobid)) als Jobid, …. und dann verglichen mit der Quelltabellenfelddefinition.