2016-06-30 7 views
1

Ich verwende SQL Server 2008 R2. Ich habe 2 Tabellen old und new und etwa 500k Reihen.So finden Sie die genaue Zeile, in der die SQL-Abfrage fehlschlägt

Ich muss Daten von old zu new konvertieren. Einige Spalten wurden geändert. Zum Beispiel in old Tabelle viele Spalten sind vom Typ varchar und in new Tabelle int.

Ich QUERY wie folgt aus:

INSERT INTO new (xxx) 
    SELECT FROM old (yyy) 

Und erhalten Fehler folgende:

Msg 245, Level 16, State 1, Line 4
Conversion failed when converting the nvarchar value 'Tammi ' to data type int.

Dieser Fehler zeigt, dass einige Zeilen mit falschen Daten in den Spalten in old Tabelle sind. (Menschlicher Faktor).

Aber wie kann ich diese falschen Zeilen finden? Ist es möglich?

Wie kann ich herausfinden, in welcher Spalte falsche Daten vorhanden sind?

+0

Überprüfung dieser Antwort - http: //stackoverflow.com/q/10517777/1080354 – gotqn

+0

Ihre Abfrage zeigt nur eine * einzige * Spalte an, 'yyy'. –

Antwort

2

Das ist ein Schmerz. Aber Werte zu finden, die nicht zu Ints umgewandelt werden kann, versuchen Sie dies:

select yyyy 
from old 
where yyyy like '%[^0-9]%'; 

In SQL Server 2012+ können Sie try_convert() verwenden:

select yyyy 
from old 
where try_convert(int, yyyy) is null; 
+0

Ich habe mehr als 50 Spalten in "alten" Tabelle. :) – Lari13

+1

@ Lari13 so was? :) mach das 50 mal. –

+0

@ Lari13 Wenn Sie 50 Spalten mit * text * Daten haben, sollten Sie nicht versuchen, sie in ganzzahlige Spalten zu erzwingen. Sie sollten zuerst Ihre Daten analysieren und entscheiden, ob die Daten fehlerhaft sind, oder Sie sollten einfach keine Integer-Spalten verwenden. SSIS hat Aufgaben, die Quellen ohne Ihren Aufwand analysieren können –

0

Könnten Sie den Code ausführen, dass diese T-SQL Anweisung erzeugt (nur die Tabellennamen ändern):

DECLARE @TableName SYSNAME = 'DataSource' 

SELECT 'SELECT * FROM ' + @TableName + ' WHERE ' + 
STUFF 
(
    (
     SELECT 'OR ISNUMERIC([' + name + '] + ''.e0'') = 0 ' 
     FROM sys.columns 
     WHERE object_id = OBJECT_ID(@TableName) 
     FOR XML PATH(''), TYPE 
    ).value('.', 'VARCHAR(MAX)') 
    ,1 
    ,3 
    ,'' 
); 

Denn Beispiel, wenn wir die folgende Tabelle:

IF OBJECT_ID('DataSource') IS NOT NULL 
BEGIN 
    DROP TABLE DataSource; 
END; 
GO 

CREATE TABLE DataSource 
(
    A VARCHAR(12) 
    ,B VARCHAR(12) 
    ,C VARCHAR(12) 
); 

GO 

INSERT DataSource ([A], [B], [C]) 
VALUES ('1', '2', '3') 
     ,('0.5', '4', '2') 
     ,('1', '2', 'A'); 

GO 

Das Skript wird diese Anweisung erzeugen:

SELECT * FROM DataSource WHERE ISNUMERIC([A] + '.e0') = 0 OR ISNUMERIC([B] + '.e0') = 0 OR ISNUMERIC([C] + '.e0') = 0 

zwei der Reihen der Rückkehr (weil A und 0.5 nicht zu int umgewandelt werden können):

enter image description here