Insert en vrac, SQL Server 2000, sauts de ligne unix

J'essaie d'insérer un .fichier csv dans une base de données avec des sauts de ligne unix. La commande que je cours est:

BULK INSERT table_name
FROM 'C:file.csv' 
WITH 
( 
    FIELDTERMINATOR = ',', 
    ROWTERMINATOR = 'n' 
) 

Si je convertit le fichier au format Windows, la charge fonctionne, mais je ne veux pas faire cette étape supplémentaire si elle peut être évitée. Des idées?

31
demandé sur Cade Roux 2009-01-26 16:37:17

8 réponses

Je me suis senti obligé de contribuer car j'avais le même problème, et j'ai besoin de lire 2 fichiers UNIX de SAP au moins deux fois par jour. Par conséquent, au lieu d'utiliser unix2dos, j'avais besoin de quelque chose avec moins d'intervention manuelle et plus automatique via la programmation.

Comme indiqué, le Char (10) fonctionne dans la chaîne sql. Je ne voulais pas utiliser une chaîne sql, et j'ai donc utilisé " + Char (10)+", mais pour une raison quelconque, cela n'a pas été compilé.

Ce qui a fonctionné très lisse était: avec (ROWTERMINATOR = '0x0a')

Problème résolu avec Hex!

J'espère que cela aide quelqu'un.

94
répondu Randy J 2010-11-17 17:03:15

Merci à tous ceux qui ont répondu mais j'ai trouvé ma solution préférée.

Lorsque vous dites à SQL Server ROWTERMINATOR='\n', il interprète cela comme signifiant le terminateur de ligne par défaut sous Windows qui est en fait "\ r \ n" (en utilisant la notation C/C++). Si votre terminateur de ligne est vraiment juste "\n", vous devrez utiliser le SQL dynamique ci-dessous.

DECLARE @bulk_cmd varchar(1000)
SET @bulk_cmd = 'BULK INSERT table_name
FROM ''C:\file.csv''
WITH (FIELDTERMINATOR = '','', ROWTERMINATOR = '''+CHAR(10)+''')'
EXEC (@bulk_cmd)

Pourquoi vous ne pouvez pas dire insertion en vrac ...(ROWTERMINATOR = CHAR (10)) est au-delà de moi. Il ne semble pas que vous puissiez évaluer les expressions dans le Avec la section de la commande.

Ce qui précède n'est de créer une chaîne de la commande et l'exécuter. Esquiver soigneusement la nécessité de créer un fichier supplémentaire ou passer par des étapes supplémentaires.

13
répondu John Oxley 2009-05-30 12:04:20

Je confirme que la syntaxe

ROWTERMINATOR = '''+CHAR(10)+'''

Fonctionne lorsqu'il est utilisé avec une commande EXEC.

Si vous avez plusieurs caractères ROWTERMINATOR (par exemple un tuyau et une ligne unix), la syntaxe pour cela est:

ROWTERMINATOR = '''+CHAR(124)+''+CHAR(10)+'''
3
répondu kr1t1kz 2011-05-17 21:27:05

C'est un peu plus compliqué que ça! Lorsque vous dites à SQL Server ROWTERMINATOR='\n', il interprète cela comme signifiant le terminateur de ligne par défaut sous Windows qui est en fait "\ r \ n" (en utilisant la notation C/C++). Si votre terminateur de ligne est vraiment juste "\n", vous devrez utiliser le SQL dynamique montré ci-dessus. Je viens de passer la meilleure partie d'une heure à comprendre pourquoi \n ne signifie pas vraiment \n lorsqu'il est utilisé avec BULK INSERT!

2
répondu 2009-05-28 12:04:23

Une option serait d'utiliser bcp , et de configurer un fichier de contrôle avec '\n' comme caractère de saut de ligne.

Bien que vous ayez indiqué que vous préféreriez ne pas le faire, une autre option serait d'utiliser unix2dos pour pré-traiter le fichier en un seul avec '\r\n' sauts de ligne.

Enfin, vous pouvez utiliser l'option FORMATFILE sur BULK INSERT. Cela utilisera un fichier de contrôle bcp pour spécifier le format d'importation.

1
répondu ConcernedOfTunbridgeWells 2009-01-26 14:00:19

Me semble qu'il y a deux avenues générales qui peuvent être prises: une autre façon de lire le CSV dans le script SQL ou de convertir le CSV au préalable avec l'une des nombreuses façons dont vous pouvez le faire (bcp, unix2dos, si c'est un roi unique d'une chose, vous pouvez probablement même utiliser votre éditeur de code

, Mais vous devrez avoir une étape supplémentaire!

Si ce SQL est lancé à partir d'un programme, vous pouvez convertir les fins de ligne dans ce programme. Dans ce cas et vous décidez de coder la conversion vous-même, voici ce que vous devez surveiller: 1. La fin de ligne peut être \n 2. ou \r\n 3. ou même \ r (Mac!) 4. bon sang, il se peut que certaines lignes aient \r \ n et d'autres \n, Toute combinaison est possible sauf si vous contrôlez d'où vient le CSV

OK, OK. Possibilité 4 est farfelue. Cela arrive dans le courrier électronique, mais c'est une autre histoire.

0
répondu Philippe Payant 2009-01-26 14:10:17

Je pense que "ROWTERMINATOR =' \n '" fonctionnerait. Je suggère d'ouvrir le fichier dans un outil qui montre des "caractères cachés" pour s'assurer que la ligne est terminée comme vous le pensez. J'utilise notepad++ pour des choses comme ça.

0
répondu BankZ 2009-01-26 14:37:11

Ça revient à ça. Unix utilise LF (ctrl-J), MS-DOS/Windows utilise CR/LF (ctrl-M/Ctrl-J).

Lorsque vous utilisez' \n ' sous Unix, il est traduit en un caractère LF. Sur MS-DOS / Windows, il est traduit en CR / LF. Lorsque votre importation s'exécute sur le fichier formaté Unix, elle ne voit qu'un LF. Par conséquent, il est souvent plus facile d'exécuter le fichier via unix2dos en premier. Mais comme vous l'avez dit dans votre question originale, vous ne voulez pas faire cela (je suppose qu'il y a une bonne raison pour laquelle vous ne pouvez pas).

Pourquoi ne peut pas vous faites:

(ROWTERMINATOR = CHAR(10))

Probablement parce que lorsque le code SQL est analysé, il ne remplace pas le caractère char(10) par le caractère LF (car il est déjà encastré dans des guillemets simples). Ou peut-être qu'il est interprété comme:

(ROWTERMINATOR =
     )

Que se passe-t-il lorsque vous faites écho au contenu de @bulk_cmd?

0
répondu BIBD 2009-01-26 16:48:51