stefan1183
Goto Top

Bulk Insert mit Formatfile

Hallo zusammen!

Ich versuche über BULK INSERT eine CSV-Datei mit einer Formatdatei einzulesen. Dabei tritt folgender Fehler auf:

Meldung 4823, Ebene 16, Status 1, Zeile 5
Massenladen ist nicht möglich. Ungültige Spaltennummer in der Formatdatei 'C:\Datenbanken\format.Fmt'.

Dies ist der Insert-Befehl:

BULK INSERT dbo.Konto_TMP
FROM 'c:\Datenbanken\Konto.csv'
WITH(FORMATFILE = 'C:\Datenbanken\format.Fmt')

Dies die Tabelle:

CREATE TABLE [dbo].[Konto](
[Buchung] [datetime] NULL,
[Valuta] [datetime] NULL,
[Auftraggeber Empfänger] [text] NULL,
[Buchungstext] [varchar](50) NULL,
[Verwendungszweck] [text] NULL,
[Betrag] [money] NULL,
[Währung] [varchar](50) NULL

Und zu guter letzt die Formatdatei:

10.0
7
1 SQLDATETIME 0 25 ";" 1 Buchung ""
2 SQLDATETIME 0 25 ";" 2 Valuta ""
3 SQLCHAR 0 150 ";" 3 [Auftraggeber Empfänger] ""
4 SQLCHAR 0 50 ";" 4 Buchungstext ""
5 SQLTEXT 0 150 ";" 5 Verwendungszweck ""
6 SQLMONEY 0 25 ";" 6 Betrag ""
7 SQLCHAR 0 50 ";\n" 7 Währung ""

Ich habe MS SQL 2008 Express auf meinem Rechner laufen.

Content-Key: 140658

Url: https://administrator.de/contentid/140658

Printed on: April 19, 2024 at 22:04 o'clock

Member: Biber
Biber Apr 14, 2010 at 18:09:14 (UTC)
Goto Top
Moin stefan1183,

bitte poste noch mal den Inhalt der (problemträchtigen) C:\Datenbanken\format.Fmt in Code-Tags.
Andernfalls ist es etwas schwierig zu erkennen, ob der inhalt passt.


Mein Verdacht ist allerdings, dass hier eher etwas anderes richtig spiegelverkehrt abgelaufen ist

  • in der DB-Tabelle sind ALLE (ich wiederhole ALLE) Datenfelder absolut beliebig befüll- oder ignorierbar... laso einfach NULLable (das hab ich ja noch nie gesehen....)
  • dagegen DARF in der CSV kein einziger Spaltenwert jemals ein NULL-Wert sein (der zweite Parameter "Längenpräfix" ist immer 0-->dann wird nie ein NULL-Wert kommen). . Das hab ich so auch selten gesehen.

Grüße
Biber
Member: stefan1183
stefan1183 Apr 14, 2010 at 18:21:19 (UTC)
Goto Top
Hallo Biber,

danke für die Antwort.

Das gröbste habe ich jetzt schon gelöst.

Ich hänge jetzt nur noch beim importieren an dem Feld "Betrag". Ich kann es zwar importieren, allerdings kann ich damit keine Berechnungen anstellen, da ich es bisher nur als char oder varchar in die Datenbank bekommen habe. Beim Convertieren in numeric, decimal, money bekomme ich eine Fehlermeldung.
In der CSV-Datei stehen Zahlenwerte wie X,XX XX,XX XXX,XX oder negativ -X,XX -XX,XX usw.

Habe übrigens heute das erste mal mit nem Formatfile was gemacht, daher wahrscheinlich das mit dem "Längenpräfix" usw. face-smile

Derzeitiger Stand:

Formatfile:
10.0
7
1 SQLCHAR	0	25	";"	1	Buchung		""
2 SQLCHAR	0	25	";"	2	Valuta		""
3 SQLTEXT	                      0                150	";"	3	Auftraggeber_Empfänger	""
4 SQLCHAR	0	50	";"	4	Buchungstext	""
5 SQLTEXT 	0	150	";"	5	Verwendungszweck	""
6 SQLCHAR	0	25	";"	6	Betrag		""
7 SQLTEXT	                      0	50	"\n"	7	Währung		"" 

   CREATE TABLE [dbo].[Konto](
	[Buchung] [varchar](50) NOT NULL,
	[Valuta] [varchar](50) NOT NULL,
	[Auftraggeber Empfänger] [text] NULL,
	[Buchungstext] [varchar](50) NULL,
	[Verwendungszweck] [text] NULL,
	[Betrag] [char](25) NOT NULL,
	[Währung] [varchar](50) NULL)

Gruß

Stefan

[Edit Biber] Code-Tags nachgetragen. [/Edit]
Member: stefan1183
stefan1183 Apr 14, 2010 at 20:15:34 (UTC)
Goto Top
Ist erledigt, klappt nun endlich face-smile

Trotzdem danke!
Member: Biber
Biber Apr 15, 2010 at 04:18:55 (UTC)
Goto Top
Moin stefan1183,

wir freuen uns natürlich mit dir, aber dennoch die neugierige Frage:
Wie hast du denn jetzt die "richtige" Interpretation der Währungswert mit Tausenderpunkten erreicht?

Da wälzte ich nämlich auch noch unausgereifte Lösungsansätze mit mir herum, die sich allerdings noch scheuten gepostet zu werden...

Grüße
Biber
Member: stefan1183
stefan1183 Apr 15, 2010 at 15:17:02 (UTC)
Goto Top
Moin!

Zunächst die beiden Tabellen in der Datenbank:

Das ist die Zieltabelle, in der das Feld Betrag schon mit dem Datentyp money deklariert ist.

CREATE TABLE [dbo].[Konto](
	[Buchung] [varchar](50) NOT NULL,
	[Valuta] [varchar](50) NOT NULL,
	[Auftraggeber Empfänger] [text] NULL,
	[Buchungstext] [varchar](50) NULL,
	[Verwendungszweck] [text] NULL,
	[Betrag] [money] NOT NULL,
	[Währung] [varchar](50) NULL
)


Dann eine Temp-Tabelle, in der "Betrag" noch als Char deklariert ist, für das einfügen der Daten aus der CSV-Datei.  


CREATE TABLE [dbo].[Konto_tmp](
	[Buchung] [varchar](50) NOT NULL,
	[Valuta] [varchar](50) NOT NULL,
	[Auftraggeber Empfänger] [text] NULL,
	[Buchungstext] [varchar](50) NULL,
	[Verwendungszweck] [text] NULL,
	[Betrag] [char](25) NOT NULL,
	[Währung] [varchar](50) NULL
)

Der Inhalt des Formatfile:

10.0
7
1 SQLCHAR	0	25	";"	1	Buchung		"SQL_Latin1_General_CP1_CI_AS"  
2 SQLCHAR	0	25	";"	2	Valuta		"SQL_Latin1_General_CP1_CI_AS"  
3 SQLTEXT	0	150	";"	3	Auftraggeber_Empfänger	"SQL_Latin1_General_CP1_CI_AS"  
4 SQLCHAR	0	50	";"	4	Buchungstext	"SQL_Latin1_General_CP1_CI_AS"  
5 SQLTEXT	0	150	";"	5	Verwendungszweck	"SQL_Latin1_General_CP1_CI_AS"  
6 SQLCHAR	0	25	";"	6	Betrag		"SQL_Latin1_General_CP1_CI_AS"  
7 SQLTEXT	0	50	"\r\n"	7	Währung		"SQL_Latin1_General_CP1_CI_AS"   

und zu guter Letzt, die Prozedur:

IF EXISTS(SELECT * FROM SYSOBJECTS WHERE TYPE = 'U' AND name = 'Konto_tmp')  
		TRUNCATE TABLE Konto_tmp


BULK INSERT dbo.Konto_tmp
FROM 'c:\Datenbanken\Konto.csv'  
WITH(FORMATFILE = 'C:\Datenbanken\format.Fmt')  

DELETE FROM dbo.Konto_tmp
WHERE Buchung = 'Buchung'  

IF EXISTS(SELECT * FROM SYSOBJECTS WHERE TYPE = 'U' AND name = 'Konto_betrag')  
		DROP TABLE Konto_betrag
		
SELECT *, CONVERT(money,Betrag)/100 AS neuer_betrag
INTO dbo.Konto_Betrag
FROM dbo.konto_tmp


INSERT INTO dbo.konto (Buchung, Valuta, [Auftraggeber Empfänger], Buchungstext, Verwendungszweck, Betrag, Währung)

SELECT Buchung, Valuta, [Auftraggeber Empfänger], Buchungstext, Verwendungszweck, neuer_betrag, Währung
FROM dbo.Konto_Betrag
WHERE Buchung NOT IN (SELECT Buchung FROM dbo.Konto)

DROP TABLE Konto_Betrag

Da das Script nicht sehr lang ist, wirst du damit sicherlich zurecht kommen.
Es gibt wahrscheinlich noch eine schönere Variante, aber zumindest funktioniert es face-smile

Gruß

Stefan