2012-07-02 1 views
3

Je dois importer les listes SAP non converties. Ces rapports ont l'air assez moche et ne sont pas bien adaptés au traitement automatisé. Cependant, il n'y a pas d'autre option. Les données sont borderd autour des symboles de moins et de tuyaux similaires à l'exemple suivant:Insertion groupée SQL SERVER ignorer les lignes déformées

02.07.2012 
-------------------- 
Report name 
-------------------- 
|Header1 |Header2 | 
|Value 11|Value1 2 | 
|Value 21|Value2 2 | 
-------------------- 

J'utilise un fichier de format et une déclaration comme ce qui suit:

SELECT Header1, Header2 
FROM OPENROWSET(BULK 'report.txt', 
FORMATFILE='formatfile_report.xml' , 
errorfile='rejects.txt', 
firstrOW = 2, 
maxerrors = 100) as report 

Malheureusement, je reçois le code d'erreur follwing:

Msg 4832, Level 16, State 1, Line 1 
Bulk load: An unexpected end of file was encountered in the data file. 
Msg 7399, Level 16, State 1, Line 1 
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 1 
Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)". 

Le fichier rejets txt contient la dernière ligne du fichier avec seulement des minuscules. Les documents rejects.txt.Error.Txt:

Row 21550 File Offset 3383848 ErrorFile Offset 0 - HRESULT 0x80004005 

Le coupable qui soulève l'erreur est évidemment la dernière ligne qui ne se conforme pas au format tel que déclaré dans le fichier de format. Cependant l'en-tête laid ne cause pas beaucoup de problèmes (au moins celui en haut).

Bien que j'ai défini l'attribut maxerror que toute une ligne déformée tue l'opération entière. Si je supprime manuellement la dernière ligne contenant tous les moins (-) tout fonctionne bien. Étant donné que cette importation doit se dérouler fréquemment et en particulier sans surveillance, le post-traitement supplémentaire n'est pas une solution sérieuse.

Quelqu'un peut-il m'aider à rendre le serveur sql moins sensible et sensible respectivement. Il est bon qu'il documente les lignes qui n'ont pas pu être chargées mais pourquoi avorte-t-il toute l'opération? Et plus loin, après une exécution d'une instruction qui a provoqué la création du reject.txt aucun autre (ou le même) instruction peut être exécutée avant que le fichier txt est supprimé manuellement:

Msg 4861, Level 16, State 1, Line 1 
Cannot bulk load because the file "rejects.txt" could not be opened. Operating system error code 80(The file exists.). 
Msg 4861, Level 16, State 1, Line 1 
Cannot bulk load because the file "rejects.txt.Error.Txt" could not be opened. Operating system error code 80(The file exists.). 

Je pense que le comportement est bizarre. S'il vous plaît, aidez-moi à le supprimer.

EDIT - FOLLOWUP: Voici le fichier de format que j'utilise:

<?xml version="1.0"?> 
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<RECORD> 
    <FIELD ID="EMPTY" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100"/> 
    <FIELD ID="HEADER1" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="100"/> 
    <FIELD ID="HEADER2" xsi:type="CharTerm" TERMINATOR="|\r\n" MAX_LENGTH="100"/> 
</RECORD> 
<ROW> 
    <COLUMN SOURCE="HEADER1" NAME="HEADER2" xsi:type="SQLNVARCHAR"/> 
    <COLUMN SOURCE="HEADER2" NAME="HEADER2" xsi:type="SQLNVARCHAR"/> 
</ROW> 
</BCPFORMAT> 
+0

J'ai trouvé un bien meilleur support quand j'utilise un fichier de format avec une largeur de colonne fixe (CharFixed au lieu de CharTerm). Ensuite, vous pouvez vérifier certaines colonnes pour le contenu attendu dans la clause where. Cependant, comme SAP fait varier la largeur de la colonne, ce n'est pas une option dans mon cas d'utilisation. – Toby

+0

Triste de voir qu'il semble vrai que SQL Server n'est tout simplement pas capable de gérer une ligne qui ne respecte pas 100% au format fourni. Pourquoi ne peut-il pas simplement ignorer et enregistrer la ligne, puis continuer au lieu d'abandonner immédiatement l'importation entière. Pire encore, une sorte de fichier d'erreur est créé et tant que celui-ci est présent (pas effacé par l'utilisateur ou le programme externe) aucune importation ne peut être lancée! N'est-ce pas un comportement étrange de logiciel professionnel? – Toby

Répondre

5

BULK INSERT est notoirement délicat et inutile en matière de traitement des données qui ne répond pas aux spécifications fournies.

Je n'ai pas fait beaucoup de travail avec les fichiers de format, mais une chose que vous pourriez envisager comme remplacement est d'utiliser BULK INSERT pour déposer chaque ligne du fichier dans une table temporaire avec une seule colonne nvarchar(max). Cela vous permet d'obtenir vos données dans SQL pour un examen plus approfondi, et vous pouvez ensuite utiliser les différentes fonctions de manipulation de chaînes pour les décomposer en données que vous voulez finalement insérer.

+0

Merci de votre contribution. En fait, je dois convenir que l'importation en vrac de serveur sql n'est pas très sophistiquée. Et non seulement l'importation, mais aussi la conversion des données est cruelle. Quelle honte pour un tel produit commercial. Quoi qu'il en soit, cette astuce avec une table temporaire d'une colonne semble être une pratique courante. Un collègue m'avait dit exactement la même chose. J'hésite cependant à le faire, car j'ai peur des impacts négatifs sur les performances! – Toby

+0

Je n'ai pas beaucoup de mesures sur le prétraitement 'BULK INSERT' comme ça. Si c'est juste la ligne à la fin du fichier qui cause le problème, vous pourriez penser à faire un petit utilitaire de console pour rechercher cette dernière ligne dans le fichier et la découper. De cette façon, vous avez quelque chose que vous pouvez intégrer dans le processus de téléchargement automatisé. – lyrisey

+0

C'est en fait à peu près ce que j'ai fini par faire. Pas très charmant cependant! Tous ces problèmes sont dus aux insuffisances des deux programmes, SAP et SQL Server. Je me demande quel produit est le pire? (Personnellement, je voterais pour SAP.) – Toby

0

J'étais dans le même problème, mais en utilisant la ligne de commande bcp le problème a été résolu, son DonT simplement prendre la dernière ligne

+1

Salut, bienvenue à stackoverflow. S'il vous plaît décrire les réponses plus. Une réponse claire aidera les gens à comprendre ce que vous voulez dire et augmentera la chance de choisir comme réponse –

0

J'ai eu le même problème. J'avais un fichier avec 115 milliards de lignes donc la suppression manuelle de la dernière rangée n'était pas une option, car je ne pouvais même pas ouvrir le fichier manuellement, car il était trop grand.

Au lieu d'utiliser la commande BULK INSERT, j'ai utilisé la commande bcp, qui ressemble à ceci: (Ouvrez un DOS cmd dans l'administrateur puis écrire)

bcp DatabaseName.dbo.TableNameToInsertIn in C:\Documents\FileNameToImport.dat -S ServerName -U UserName -P PassWord 

Il est sur la même vitesse que d'insertion en bloc dans la mesure comme je peux le dire (m'a pris seulement 12 minutes pour importer mes données). Lorsque je regarde le moniteur d'activité, je peux voir une insertion en bloc, donc je suppose qu'il se connecte de la même manière lorsque la base de données est en mode de récupération en bloc.

Questions connexes