it-swarm.com.de

Wie identifiziere ich die Spalte (n), die für "Zeichenfolge oder Binärdaten werden abgeschnitten" verantwortlich sind.

Ich generiere einige Abfragen automatisch mit Code, den ich aus einer Remote-Pg-Datenbank in SELECT geschrieben und in eine lokale SQL Server-Datenbank eingefügt habe. Einer von ihnen generiert jedoch diesen Fehler:

[Microsoft] [ODBC SQL Server-Treiber] [SQL Server] Zeichenfolge oder Binärdaten werden abgeschnitten. (SQL-22001) [Status war 22001 jetzt 01000]

[Microsoft] [ODBC SQL Server-Treiber] [SQL Server] Die Anweisung wurde beendet. (SQL-01000) in der Zeile 106.\Insert.pl.

Wie finde ich heraus, welche Spalte diesen Fehler erzeugt und welche Länge für die Eingabe fehlt? Gibt es eine Möglichkeit, dies zu tun, ohne alle varchar brutal zu erraten?

32
Evan Carroll

Letztendlich konnte ich keinen Weg finden, die Spalteninformationen zu erhalten, ohne sie selbst zu schreiben.

Diese Fehlermeldung wurde generiert von DBD::ODBC , Sie können jedoch auch sys.columns (max_length) verwenden (ich weiß es einfach nicht Wie).

Ich habe Code wie diesen über meiner Spaltenliste verwendet, um eine Liste von Arrays mit zwei Elementen zu erhalten, COLUMN_NAME Und MAX_LENGTH (Dokumentiert in DBI column_info() ).

my @max_lengths = map [ @{$_->fetchall_arrayref->[0]}[3,6] ]
    , map $dbh_mssql->column_info('database', 'dbo', $dest_table, $_)
    , @col_mssql
;

Dann habe ich die Ausnahmen auf INSERT abgefangen und etwas Nützliches ausgedruckt. In diesem Beispiel sind @$row Die Daten, die an sth->execute() gesendet werden

if ([email protected]) {
        warn "[email protected]\n";
        for ( my $idx=0; $idx <= $#{ $row }; $idx++ ) {
                Dumper {
                        maxlength => $max_lengths[$idx]->[1]
                        , name    => $max_lengths[$idx]->[0]
                        , length  => length( $row->[$idx] )
                        , content => $row->[$idx]
                };
        }
        die;
}

Bitte stimmen Sie auch ab und stimmen Sie der anderen Antwort zu

1
Evan Carroll

Nein, es wird nirgendwo protokolliert. Gehen Sie abstimmen und geben Sie Ihren Business Case an. Dies ist eine auf der langen Liste der Dinge, die in SQL Server behoben werden sollten.

Dies wurde vor Jahren bei Connect angefordert (wahrscheinlich zuerst im SQL Server 2000- oder 2005-Zeitrahmen), dann erneut beim neuen Feedback-System:

Und jetzt wurde es in den folgenden Versionen geliefert:

Im allerersten öffentlichen CTP von SQL Server 2019 wird es nur unter dem Trace-Flag 460 angezeigt. Dies klingt irgendwie geheim, wurde jedoch in diesem Microsoft-Whitepaper veröffentlicht. Dies ist in Zukunft das Standardverhalten (kein Ablaufverfolgungsflag erforderlich). Sie können dies jedoch über eine neue Konfiguration mit Datenbankbereich VERBOSE_TRUNCATION_WARNINGS Steuern.

Hier ist ein Beispiel:

USE tempdb;
GO
CREATE TABLE dbo.x(a char(1));

INSERT dbo.x(a) VALUES('foo');
GO

Ergebnis in allen unterstützten Versionen vor SQL Server 2019:

Nachricht 8152, Ebene 16, Status 30, Zeile 5
String oder Binärdaten würden abgeschnitten werden.
Die Anweisung wurde beendet.

Jetzt auf SQL Server 2019-CTPs mit aktiviertem Trace-Flag:

DBCC TRACEON(460);
GO

INSERT dbo.x(a) VALUES('foo');
GO
DROP TABLE dbo.x;
DBCC TRACEOFF(460);

Das Ergebnis zeigt die Tabelle, die Spalte und die ( abgeschnittenen , nicht vollen ) Wert:

Nachricht 2628, Ebene 16, Status 1, Zeile 11
Zeichenfolge oder Binärdaten werden in der Tabelle 'tempdb.dbo.x', Spalte 'a' abgeschnitten. Abgeschnittener Wert: 'f'.
Die Anweisung wurde beendet.

Bis Sie zu einer unterstützten Version/CU oder zu einer Azure SQL-Datenbank wechseln können, können Sie Ihren "automagischen" Code so ändern, dass die maximale Länge von sys.columns Zusammen mit dem Namen abgerufen wird, den Sie ohnehin erhalten müssen und dann Anwenden von LEFT(column, max_length) oder einem beliebigen PG-Äquivalent. Oder, da dies nur bedeutet, dass Sie stillschweigend Daten verlieren, müssen Sie herausfinden, welche Spalten nicht übereinstimmen, und die Zielspalten so korrigieren, dass sie zu allen Daten aus der Quelle passen. Angesichts des Metadatenzugriffs auf beide Systeme und der Tatsache, dass Sie bereits eine Abfrage schreiben, die automatisch mit Quell-> Zielspalten übereinstimmen muss (andernfalls wäre dieser Fehler kaum Ihr größtes Problem), sollten Sie keine Brute-Force-Maßnahmen ergreifen müssen überhaupt raten.

37
Aaron Bertrand

Wenn Sie Zugriff haben, um SQL Server-Import- und Exportassistent in SQL Server Management Studio auszuführen (klicken Sie mit der rechten Maustaste auf Datenbank> Aufgaben> Daten importieren ...), erstellen Sie eine Aufgabe, die mithilfe Ihrer Abfrage aus SQL Client importiert wird als Datenquelle zur Zieltabelle.

Bevor Sie den Import ausführen, können Sie die Datenzuordnung überprüfen und erfahren, welche Spalten inkonsistente Feldtypen aufweisen. Wenn Sie die Importaufgabe ausführen, erfahren Sie, welche Spalte (n) nicht importiert werden konnten.

Beispielvalidierungswarnung:

Warnung 0x802092a7: Datenfluss Aufgabe 1: Das Einfügen von Daten aus der Datenflussspalte "NARRATIVE" mit einer Länge von 316 in die Datenbankspalte "NARRATIVE" mit einer Länge von 60 kann auftreten. (SQL Server-Import- und Export-Assistent)

2
bubbassauro

Schließlich Microsoft hat beschlossen, aussagekräftige Informationen bereitzustellen für String or binary would be truncated ab SQL Server 2016 SP2 CU, SQL Server 2017 CU12 und in SQL Server 2019.

Die Informationen enthalten jetzt sowohl die betreffende Tabellenspalte (vollständig qualifizierter Name) als auch den fehlerhaften Wert (mit 120 Zeichen abgeschnitten):

Nachricht 2628, Ebene 16, Status 1, Zeile x Zeichenfolge oder Binärdaten werden in der Tabelle 'TheDb.TheSchema.TheTable', Spalte 'TheColumn' abgeschnitten. Abgeschnittener Wert: '...'. Die Anweisung wurde beendet.

1
Alexei