Je n'arrive pas à comprendre comment cela se passe.
Voici un exemple de fichier que j'essaie d'insérer en bloc dans SQL Server 2005:
***A Nice HEADER HERE***
0000001234|SSNV|00013893-03JUN09
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
Voici ma déclaration d'insertion en vrac:
BULK INSERT sometable
FROM 'E:\filefromabove.txt
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
Mais, pour une raison quelconque, le seul résultat que je puisse obtenir est le suivant:
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
Le premier enregistrement est toujours ignoré, sauf si j'enlève complètement l'en-tête et n'utilise pas le paramètre FIRSTROW. Comment est-ce possible?
Merci d'avance!
Je ne pense pas que vous puissiez sauter des lignes dans un format différent avec BULK INSERT
/BCP
.
Quand je lance ceci:
TRUNCATE TABLE so1029384
BULK INSERT so1029384
FROM 'C:\Data\test\so1029384.txt'
WITH
(
--FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
SELECT * FROM so1029384
Je reçois:
col1 col2 col3
-------------------------------------------------- -------------------------------------------------- --------------------------------------------------
***A Nice HEADER HERE***
0000001234 SSNV 00013893-03JUN09
0000005678 ABCD 00013893-03JUN09
0000009112 0000 00013893-03JUN09
0000009112 0000 00013893-03JUN09
Il semble que cela nécessite le '|' même dans les données d'en-tête, car elles sont lues jusqu'à la première colonne - engloutissant une nouvelle ligne dans la première colonne. Évidemment, si vous incluez un paramètre de terminaison de champ, il s'attend à ce que chaque ligneDOITen avoir un.
Vous pouvez supprimer la ligne avec une étape de pré-traitement. Une autre possibilité consiste à sélectionner uniquement des lignes complètes, puis à les traiter (en excluant l'en-tête). Ou utilisez un outil capable de gérer cela, comme SSIS.
Peut-être vérifier que l'en-tête a la même fin de ligne que les lignes de données réelles (comme spécifié dans ROWTERMINATOR
)?
Mise à jour: à partir de MSDN :
L'attribut FIRSTROW n'est pas destiné à ignorer les en-têtes de colonne. Ignorer les en-têtes n'est pas pris en charge par l'instruction BULK INSERT. Lorsque vous ignorez des lignes, le moteur de base de données SQL Server examine uniquement les terminateurs de champ et ne valide pas les données dans les champs des lignes ignorées.
J'ai trouvé plus facile de simplement lire la ligne entière dans une colonne, puis d'analyser les données à l'aide de XML.
IF (OBJECT_ID('tempdb..#data') IS NOT NULL) DROP TABLE #data
CREATE TABLE #data (data VARCHAR(MAX))
BULK INSERT #data FROM 'E:\filefromabove.txt' WITH (FIRSTROW = 2, ROWTERMINATOR = '\n')
IF (OBJECT_ID('tempdb..#dataXml') IS NOT NULL) DROP TABLE #dataXml
CREATE TABLE #dataXml (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, data XML)
INSERT #dataXml (data)
SELECT CAST('<r><d>' + REPLACE(data, '|', '</d><d>') + '</d></r>' AS XML)
FROM #data
SELECT d.data.value('(/r//d)[1]', 'varchar(max)') AS col1,
d.data.value('(/r//d)[2]', 'varchar(max)') AS col2,
d.data.value('(/r//d)[3]', 'varchar(max)') AS col3
FROM #dataXml d
BULK INSERT TextData
FROM 'E:\filefromabove.txt'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '|', --CSV field delimiter
ROWTERMINATOR = '\n', --Use to shift the control to next row
ERRORFILE = 'E:\ErrorRows.csv',
TABLOCK
)