J'ai essayé la commande suivante
USE <DBNAME>
SELECT 'exec master..xp_cmdshell'
+ ' '''
+ 'bcp'
+ ' ' + TABLE_CATALOG + '.' + TABLE_SCHEMA + '.' + TABLE_NAME
+ ' out'
+ ' D:\'
+ TABLE_NAME + '.csv'
+ ' -c'
+ ' -t,'
+ ' -T'
+ ' -S' + @@SERVERNAME
+ ''''
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
Je veux obtenir les données au format suivant.
Le format sera un fichier texte délimité par des tuyaux, avec des qualificatifs de texte entre guillemets doubles et sans ligne d'en-tête. Comment modifier ou écrire la commande BCP pour obtenir le résultat requis.
Mon jeu de données n'est qu'une table client.
CustomerID CustomerName ContactName Address City PostalCode Country
1 Alfreds Futterkiste Maria Anders Obere Str. 57 Berlin 12209 Germany
Le format de données requis est
1|"Alfreds Futterkiste"|"Maria Anders"|"Obere Str. 57 Berlin"|12209|"Germany"
Maintenant que je comprends mieux que vous essayez d'extraire des données, voici une nouvelle réponse. Cela extrait simplement les données d'une table que j'ai créée dans tempdb.
use tempdb
-- drop table mytable
create table mytable
(id int, customer_name varchar(55), cityname varchar(55), statename varchar(55))
insert into mytable
values (1, 'a', 'a city', 'a state')
, (2, 'b', 'b city', 'b state')
, (3, 'c', 'c city', 'c state')
, (4, 'd', 'd city', 'd state')
select cast(id as varchar(10)), customer_name, cityname, statename from mytable
Ce qui se traduit par la commande bcp suivante
bcp "select cast(id as varchar(10)), customer_name, cityname, statename from mytable" queryout c:\temp\myTable.csv /S.\instance_name /d tempdb /c /t"|" -T
Mise à jour Cette commande bcp ajoutera des guillemets doubles
exec Master..xp_Cmdshell 'bcp "select cast(id as varchar(10)), quotename(customer_name,char(34)), quotename(cityname,char(34)), quotename(statename,char(34)) from mytable" queryout "c:\temp\myTable.csv" /S.\instance_name /d tempdb /c /t"|" /T'
ou tout simplement avec bcp
bcp "select cast(id as varchar(10)), quotename(customer_name,char(34)), quotename(cityname,char(34)), quotename(statename,char(34)) from mytable" queryout "c:\temp\myTable.csv" /S.\instance_name /d tempdb /c /t"|" /T
Cette commande bcp utilise la fonction quotename . Ce qui vous permet de délimiter votre sortie en utilisant les caractères que vous aimez.
Une autre option, au moins pour le dire, est d'utiliser les fichiers au format BCP. Les fichiers de format permettent de spécifier les propriétés de colonne, y compris le délimiteur. Les délimiteurs sont généralement constitués de n'importe quel caractère, mais vous pouvez ajouter des guillemets doubles dans les délimiteurs de champ appropriés pour produire des valeurs qualifiées de texte.
Vous pouvez effectuer un test simple en demandant à BCP de générer un fichier de format, de le modifier, puis de faire un extrait avec. Ensuite, vous avez au moins un modèle de base d'un fichier à mettre à jour pour des cas spécifiques.
Alors essayez:
bcp sys.objects format nul -f TestFormat.xml -x -T -c -t"|"
Si vous modifiez TestFormat.xml , vous verrez des éléments tels que:
...
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="256" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="12"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="12"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="12"/>
...
Ajoutez "
Avant et/ou après les symboles de tuyau appropriés pour injecter les qualificateurs de texte:
...
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="|"" MAX_LENGTH="256" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR=""|" MAX_LENGTH="12"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="|"" MAX_LENGTH="12"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR=""|" MAX_LENGTH="12"/>
...
Exécutez ensuite l'extrait en spécifiant ce fichier de format:
bcp sys.objects out Output.txt -T -f TestFormat.xml
Il devrait produire quelque chose comme:
sysrscols|"3"||"4"|0|S |SYSTEM_TABLE|2012-02-10 20:16:00.707|2012-02-10 20:16:00.713|1|0|0
sysrowsets|"5"||"4"|0|S |SYSTEM_TABLE|2009-04-13 12:59:11.093|2012-02-10 20:16:01.943|1|0|0
sysclones|"6"||"4"|0|S |SYSTEM_TABLE|2012-02-10 20:16:01.523|2012-02-10 20:16:01.530|1|0|0
Je ne sais pas comment obtenir un qualificatif de texte à l'extrême gauche (premier caractère du fichier) en dehors de le sélectionner en tant que littéral de chaîne (c'est-à-dire '"'
), Puis de ne spécifier aucun délimiteur de champ entre les deux premiers des champs.
Pour plus d'informations sur les fichiers au format XML:
Deux notes (qui s'appliquent que vous utilisiez ou non Format Files):
En ce qui concerne les formats de date, il existe de nombreuses options qui peuvent être spécifiées dans les fichiers de format, alors regardez-les d'abord. Si cela ne fonctionne pas, vous pouvez toujours utiliser la fonction FORMAT (si vous utilisez SQL Server 2012 ou plus récent) car l'exemple ci-dessus exporte tous champs comme "caractère"
!! SUPREMO IMPORTANTE !!: La principale raison d'utiliser des qualificateurs de texte dans des fichiers plats délimités est de pouvoir gérer des données comportant des caractères de délimitation incorporés. Ainsi, en utilisant un qualificateur de texte dans ce contexte, vos données de chaîne peuvent avoir des symboles de canal et être toujours en mesure d'analyser correctement les champs. Génial. Tout est fait maintenant, non? FAUX! L'utilisation des qualificateurs de texte corrige les incorporés délimiteurs, mais maintenant vous devez tenir compte des qualificateurs de texte incorporés. Cela signifie que vous devez échapper aux guillemets doubles dans vos données, sinon cela interrompra l'importation. Par exemple:
1|"Alfreds Futterkiste"|"Maria Anders"|"Obere Str. 57 Berlin"|12209|"Germany"
2|"Johnny "knuckles" Malone"|"Other Name"|"123 Fake Street, IL"|60606|"US"
L'enregistrement n ° 2 ci-dessus sera considéré comme une ligne indésirable. Ou peut être importé en tant qu'entrée malformée, selon la façon dont le processus d'importation valide les données. Vous devez donc remplacer un guillemet simple par deux guillemets (le moyen standard pour échapper les qualificateurs de texte) via REPLACE(FieldName, '"', '""')
afin que l'enregistrement # 2 se présente comme suit:
2|"Johnny ""knuckles"" Malone"|"Other Name"|"123 Fake Street, IL"|60606|"US"
Et par souci d'exhaustivité, d'autres options d'exportation incluent: