web-dev-qa-db-fra.com

Déterminez le ROW ayant provoqué l'erreur "fin inattendue du fichier" dans BULK INSERT?

je fais un insert en vrac:

DECLARE @row_terminator CHAR;
SET @row_terminator = CHAR(10); -- or char(10)

DECLARE @stmt NVARCHAR(2000);
SET @stmt = '
  BULK INSERT accn_errors
   FROM ''F:\FullUnzipped\accn_errors_201205080105.txt''
   WITH 
      (
        firstrow=2,
FIELDTERMINATOR = ''|''  ,
ROWS_PER_BATCH=10000
   ,ROWTERMINATOR='''+@row_terminator+'''
   )'
exec sp_executesql @stmt;

et j'obtiens l'erreur suivante:

Msg 4832, Level 16, State 1, Line 2
Bulk load: An unexpected end of file was encountered in the data file.
Msg 7399, Level 16, State 1, Line 2
The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.
Msg 7330, Level 16, State 2, Line 2
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".

existe-t-il un moyen de savoir sur quelle emprise cette erreur s'est produite?

je suis en mesure d'importer 10 000 000 de lignes sans problème et une erreur se produit après

Pour localiser la ligne problématique, utilisez le spécificateur errorfile.

BULK INSERT myData
FROM 'C:\...\...\myData.csv'
WITH (
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n',
ERRORFILE = 'C:\...\...\myRubbishData.log' 
);

myRubbishData.log aura les lignes incriminées et un fichier compagnon myRubbishData.log.txt vous donnera les numéros de lignes et les décalages dans le fichier. 

Exemple de fichier compagnon:

Row 3 File Offset 152 ErrorFile Offset 0 - HRESULT 0x80004005
Row 5 File Offset 268 ErrorFile Offset 60 - HRESULT 0x80004005
Row 7 File Offset 384 ErrorFile Offset 120 - HRESULT 0x80004005
Row 10 File Offset 600 ErrorFile Offset 180 - HRESULT 0x80004005
Row 12 File Offset 827 ErrorFile Offset 301 - HRESULT 0x80004005
Row 13 File Offset 942 ErrorFile Offset 416 - HRESULT 0x80004005
46
user1588622

Fun, fun, fun. Je n'ai pas trouvé le bon moyen de résoudre ces problèmes, alors j'utilise la force brute. C'est-à-dire que les options FirstRow et LastRow sont très utiles.

Commencez avec LastRow = 2 et continuez d'essayer. Chargez les résultats dans une table à jeter que vous pouvez facilement tronquer.

Et, vous devez également garder à l’esprit que la première rangée pourrait également vous causer des problèmes.

5
Gordon Linoff

J'ai un fichier csv que j'importe d'importer en vrac

BULK INSERT [Dashboard].[dbo].[3G_Volume]
FROM 'C:\3G_Volume.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n'
)
GO

Habituellement, j'ai utilisé ce script et il n'a pas de problèmes, mais dans de rares occasions.

Je rencontre cette erreur ..

"Le fournisseur de base de données OLE" BULK "du serveur lié" (null) "a signalé une erreur. Le fournisseur n'a fourni aucune information sur l'erreur."

Cela se produit généralement lorsque la dernière ligne a des valeurs vides (null).

Vous devez lier votre fichier csv dans MS Access db pour vérifier les données .. (Si votre csv ne dépasse pas 1,4 million de lignes, vous pouvez l'ouvrir dans Excel)

Étant donné que mes données sont environ 3 millions de lignes, je dois utiliser access db.

Puis vérifiez le nombre de dernières lignes avec des blancs et soustrayez le nombre de lignes nulles à votre nombre total de lignes pour csv.

si vous avez 2 lignes vierges à la fin et que le nombre total de lignes est 30000005 .__, le script deviendra comme ceci.

BULK
INSERT [Dashboard].[dbo].[3G_Volume]
 FROM 'C:\3G_Volume.csv'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '","',
ROWTERMINATOR = '\n',
Lastrow = 30000003
)
GO

Salut ... Mhelboy

3
Mhelboy

Si CHAR (10) est le terminateur de ligne, je ne pense pas que vous puissiez le mettre entre guillemets comme vous le faites dans BULK INSERT. Il existe un moyen non documenté de l'indiquer, cependant:

ROWTERMINATOR = '0x0A'
3
Steve Kass

Ouais - BULK INSERT aurait fait un peu plus de détail dans ses messages d'erreur, et la seule solution consiste à utiliser l'approche de la force brute, comme Gordon l'a justement souligné. Tout d’abord, cependant, en fonction de l’erreur que vous obtenez, il ne comprend pas votre terminateur de ligne ou il manque un terminateur de ligne à la fin du fichier. Utiliser FIRSTROW et LASTROW aidera à déterminer cela.

Donc, vous devez faire ce qui suit:

  1. Vérifiez qu’il existe un terminateur de ligne à la fin du fichier. Sinon, mettez-en un et réessayez. Assurez-vous également que la dernière ligne contient tous les champs nécessaires. Il dit "EOF", alors c'est votre problème.
  2. Êtes-vous sûr qu'il y a un LF à la fin de chaque ligne? Essayez un CR (\ n, 0x0D) et voyez si cela fonctionne.
  3. Ne fonctionne toujours pas? Essayez de régler LASTROW = 2 et essayez à nouveau. Ensuite, essayez LASTROW = 3. Si votre fichier contient plus de trois lignes et que cette étape échoue, le terminateur de ligne ne fonctionne pas.
2
Peter

J'ai rencontré le même problème. J'avais écrit un script Shell pour créer un fichier .csv sous Linux. J'ai pris ce fichier .csv sous Windows et j'ai essayé de charger en bloc les données. Il n’a pas "aimé" les virgules .... Ne me demandez pas pourquoi, mais j’ai changé en un délimiteur * dans l’importation en masse et ai effectué une recherche et une substitution pour une virgule avec * dans mon .csv .. .. J'ai changé pour un ~ comme séparateur, cela a fonctionné ... l'onglet a également fonctionné - la virgule ne lui a pas plu ... J'espère que cela aidera quelqu'un. 

1
user2125311

D'après mon expérience, cela est presque toujours causé par quelque chose dans les deux dernières lignes. tail le fichier d'importation et il devrait toujours vous donner l'échec. Puis ouvrez-le dans un éditeur de texte intégral qui vous permet de voir des caractères non imprimables tels que CR, LF et EOF. Cela devrait vous permettre de continuer à travailler, même si vous ne savez pas pourquoi. Exemple: BULK INSERT échoue avec le terminateur de ligne sur la dernière ligne

0
feetwet

J'ai contourné le problème en convertissant tous les champs en chaînes, puis en utilisant un FIELDTERMINATOR commun. Cela a fonctionné:

BULK INSERT [dbo].[workingBulkInsert]  
FROM 'C:\Data\myfile.txt' WITH (
   ROWTERMINATOR = '\n', 
   FIELDTERMINATOR = ',' 
)

Mon fichier de données ressemble à ceci maintenant:

"01502","1470"
"01504","686"
"02167","882"
"106354","882"
"106355","784"
"106872","784"

Le deuxième champ était un type décimal sans délimiteur de guillemets (comme 1470.00). Le formatage des deux en tant que chaînes a éliminé l'erreur.

0
Karl Hoaglund