web-dev-qa-db-fra.com

Spécifier le délimiteur dans OpenRowset Bulk Insert

J'essaie d'insérer des données à partir de fichiers CSV dans des tables à l'aide d'un curseur et d'une insertion en vrac de rowet ouverte. Cela fonctionne pour moi 99% des temps, mais si l'un des champs des fichiers CSV contient une virgule (,), l'importation de données est ruinée et que toutes les colonnes sont importées une colonne après leur place. Par exemple, il devrait ressembler à ceci:

timestamp   username   name         IP       title
20190331    ABCD12G    david hertz  1.1.1.1   null

Mais si j'ai une virgule dans la colonne Nom (par exemple), cela ressemblera à ce que:

timestamp   username   name      IP      title
20190331    ABCD12G    david    hertz   1.1.1.1

exemple de CSV:

username,name,ip,title
ABCD12G,david,hertz,1.1.1.1,''

C'est la syntaxe que j'utilise:

insert into [player table]
select 20190331,* FROM  OPENROWSET(BULK  'D:\folder\2019\03-
31\Player_statistics.csv', FIRSTROW = 2, 
FORMATFILE='D:\folder\test\xml\Player_statistics.xml')
 as t1

comment puis-je changer cela pour ignorer la virgule au milieu d'un mot? (Je ne peux pas limiter le CSV depuis sa prise d'un autre client qui ne limitera pas les caractères.

le XML que j'utilise pour l'importation avec OpenRowset:

xml

lorsque vous effectuez une insertion de vrac régulière, vous avez une option pour spécifier le délimiteur fielterminator = '"," ", je n'ai pas pu trouver quelque chose comme ça dans OpenRowset.

Qu'est-ce qui peut aider à résoudre ce problème?

2
sql_girl

mais si l'un des champs des fichiers CSV contient une virgule (,)

Si toutes les lignes contiennent une virgule, la solution peut être

<ROW>  
  <COLUMN SOURCE="1" NAME="username" xsi:type="SQLSMALLINT"/>  
  <COLUMN SOURCE="2" NAME="name1" xsi:type="SQLNVARCHAR"/>  
  <COLUMN SOURCE="3" NAME="name2" xsi:type="SQLNVARCHAR"/>  
  <COLUMN SOURCE="4" NAME="IP" xsi:type="SQLNVARCHAR"/>  
  <COLUMN SOURCE="5" NAME="title" xsi:type="SQLNVARCHAR"/>  
</ROW> 
INSERT INTO [player table]
SELECT 20190331, 
       username, 
       name1+','+name2, 
       IP, 
       title 
FROM  OPENROWSET( BULK 'D:\folder\2019\03-31\Player_statistics.csv', 
                  FIRSTROW = 2, 
                  FORMATFILE='D:\folder\test\xml\Player_statistics.xml') t1

Si seulement certaines lignes contiennent des virgules et aucun title est null/vide, puis essayez

INSERT INTO [player table]
SELECT 20190331, 
       `username`, 
       CASE WHEN title IS NULL 
            THEN name1
            ELSE name1+','+name2 END, 
       CASE WHEN title IS NULL 
            THEN name2
            ELSE IP END, 
       CASE WHEN title IS NULL 
            THEN IP
            ELSE title END
       IP, 
       title 
FROM  OPENROWSET( BULK 'D:\folder\2019\03-31\Player_statistics.csv', 
                  FIRSTROW = 2, 
                  FORMATFILE='D:\folder\test\xml\Player_statistics.xml') t1

Si quelque chose title est null/vide, je ne trouve pas un moyen simple de distinguer.

MISE À JOUR

La solution peut être: Divisez votre CSV sur deux champs uniquement - username _ et tout le mou, le relâchement peut alors être divisé en des champs distincts à l'aide de fonctions de chaîne courantes dans la partie sélectionnée de la requête importée (peut-être utiliser des variables intermédiaires dans les calculs de la chaîne).

1
Akina

Vous pouvez trouver votre réponse du lien ci-dessous:

https://stackoverflow.com/questions/4123875/commas-within-csv-data

Nous avons également utilisé le BCP et le transfert, ce qui remplaçait cependant des virgules avec de l'espace (si possible) après avoir accepté le client en fonction de la gravité de la colonne ou de.

J'espère que cela t'aides.

0
Learning_DBAdmin