Einfügen von GUIDs mit SqlBulkCopy

8

Ich versuche eine Masseneinfügung mit der Klasse SqlBulkCopy aus Flatfiles durchzuführen, die vom Import-Export-Assistenten von SQL Server Management erstellt wurden. Die Dateien sind durch Kommas getrennt.

Eine Zeile in der Datei kann folgendermaßen aussehen:

  

{DCAD82A9-32EC-4351-BEDC-2F8291B40AB3} ,, {ca91e768-072d-4e30-aaf1-bfe32c24008f}, 900001: 1792756, 900171, 1792757, basladdning, 2011-04-29 02: 54: 15.380000000, basladning , 2011-04-29 02: 54: 15.380000000, {20A3C50E-8029-41DE-86F1-DDCDB9A78BA5}

Der Fehler, den ich bekomme, ist:

  

System.InvalidOperationException wurde nicht behandelt
  Message = Der angegebene Wert vom Typ String aus der Datenquelle kann nicht in Typ konvertiert werden   uniqueidentifier der angegebenen Zielspalte.

Das Problem ist also die Umwandlung von Zeichenfolge in GUID.

Ich habe Folgendes versucht:

  • Versuchte verschiedene Kodierungen, UTF8 und ANSI
  • Entfernte das {}, das die GUIDS umgibt
  • Hinzugefügt '' um die GUIDS, mit und ohne {}

Irgendwelche Vorschläge? In der flachen Datei, in der das '' ist, ist eine Spalte, die auch Guid als Datentyp hat. Die Spalte ist NULL, wo der Assistent sie als "" exportiert hat. Kann das das Problem sein?

Der Code:

%Vor%

Tabellendefinition:

%Vor%     
Magnus A 29.11.2012, 13:54
quelle

4 Antworten

4

Das Problem ist, dass die leere Spalte in {DCAD82A9-32EC-4351-BEDC-2F8291B40AB3},,{ca91e768-072d-4e30-aaf1-bfe32c24008f} als '' anstatt als NULL interpretiert wird. Ich habe gerade einen INSERT STATEMENT in meiner lokalen Datenbank versucht, und dieser Fehler ist verschwunden, als ich NULL anstelle von '' angegeben habe Es gibt einen weiteren Fehler, den Sie möglicherweise bekommen:

%Vor%

Der Grund dafür ist, dass SQL nur eine dreistellige Dezimalgenauigkeit für Millisekunden erlaubt. Sie müssen also '2011-04-29 02:54:15.380000000' auf '2011-04-29 02:54:15.380' abrunden, und es wird gut funktionieren.

Ein Weg, dies zu tun, wäre wie erwähnt hier Alternativ können Sie CsvReader-Code ändern, um DBNULL zurückzugeben, wenn der Wert string.Empty in CsvReader.GetValue (int) -Funktion ist. Schauen Sie sich hier

an >     
tranceporter 29.11.2012, 16:03
quelle
2

Fügen Sie in Ihrer DataTable.Columns.Add den Datentyp als zweiten Parameter ein. Das sollte den Trick machen. Beispiel:

%Vor%     
Paul Kar. 25.11.2016 17:10
quelle
0

Eine Standardeinfügung in eine uniqueidentifier-Spalte würde so aussehen (getestet und funktioniert), so dass die formative Frage beantwortet wird. Erlaubt die Spalte Nullen?

INSERT in dbo.TableName ([GUID]) WERTE ('20A3C50E-8029-41DE-86F1-DDCDB9A78BA5')

    
smoore4 29.11.2012 14:10
quelle
0

Ich glaube, ich fand eine Antwort für diejenigen, die eine beliebte Freeware-Code-Klasse namens BulkDataReader verwenden. Ich habe das gleiche Problem und ich habe versucht, dies vor ein paar Jahren zu posten, war aber seit ich ein anderes fragte Frage und keine Antwort, dass Beitrag wurde entfernt. Das ist in Ordnung, ich habe nicht bemerkt, dass das gegen die Regeln war.

Diesmal habe ich eine Antwort, also hoffentlich wird dieser Beitrag hier bleiben. Ich werde den Setup-Teil meines Problems verlassen, so dass es gut definiert ist und niemand verwirrt ist, warum die Lösung für sie nicht funktioniert. Ich habe den Code für die BulkDataReader-Klasse erhalten ein Kollege und es scheint, dass er das von einer anderen bekannten Antwortquelle bekommen hat, so dass jeder weiß, wie man BuldDataReader von einer Suchmaschine findet.

Dieses Problem ist wie folgt:

Ich habe auch alle möglichen Formate für die GUIDS in der CSV-Datei ausprobiert, einschließlich: N'3192E434-F479-4B32-B516-AC658F4B7B89 ' {3192E434-F479-4B32-B516-AC658F4B7B89} (3192E434-F479-4B32-B516-AC658F4B7B89) "{3192E434-F479-4B32-B516-AC658F4B7B89}"

Eine echte Beispielzeile aus meiner CSV wäre: 1, AAPL, 452.2012,2013-01-24 13: 24: 27.000,3192E434-F479-4B32-B516-AC658F4B7B89,3192E434-F479-4B32-B516-AC658F4B7B89

Wenn ich die 2 Guids entferne und in eine Tabelle ohne diese Spalten importiere, funktioniert es gut. Mit den Guids to Unique Identifier-Spalten erhalte ich diesen Fehler: Message = {"Der angegebene Wert vom Typ String aus der Datenquelle kann nicht in den eindeutigen Typ der angegebenen Zielspalte konvertiert werden."}

Mein Steuercode ist ziemlich einfach, wenn der BulkDataReader ziemlich mühsam ist, also sollten Sie vorbereitet sein, wenn Sie versuchen, ihn zu debuggen.

%Vor%

Der Fehler tritt also tatsächlich in der .NET SqlBulkCopy-Klasse auf. Es passiert jedoch direkt nachdem der BulkDataReader einen Guid-Wert liest. Diese GetValue-Methode wird von Extern aufgerufen Code bedeutet, dass er in den Leitungen zwischen dem streamReader des BulkDataReader und dem StreamWriting-Kram in der SqlBulkCopy-Klasse verborgen ist. Es war nicht nötig, all das zu untersuchen mein Lieblingsreflexionsprogramm. Ich fand, dass, wenn die Methode IDataRecord.GetValue (int i) des BulkDataReader eine Zeichenfolge zurückgibt, die wirklich ein Guid ist, SqlBulkCopy diese Zeichenfolge nicht konvertieren kann zu einem eindeutigen Bezeichner, egal welches Format es hat. Es gibt wahrscheinlich ein obskures und kodierendes Format, aber ich konnte keins finden, das funktionieren würde. Wenn ich jedoch einfach den Wert als zurücksende ein richtiger System.Guid-Typ, dann konvertiert SqlBulkCopy es in eindeutige Kennung gut. Also, eine einfache Lösung für das, was wie ein albtraumhaftes Serialisierungsproblem aussieht. Kopieren Sie einfach über die gesamte IDataRecord.GetValue (int i) -Methode mit diesem und es sollte funktionieren. Ich habe viele der CLR-SQL-Datentypen ausprobiert, aber nicht alle von ihnen, so dass es immer noch eine andere gibt, bei der Sie müssen Spiele dieses Deserialisierungsspiel, aber das sollte das Problem größtenteils lösen.

%Vor%

Ich hoffe, das hilft jemandem und tut mir leid, dass ich die Blogregeln das erste Mal gebrochen habe.

    
Doug 07.02.2013 01:18
quelle