Utilisez BCP pour importer le fichier CSV à SQL 2005 ou 2008
-
06-09-2019 - |
Question
J'ai un fichier CSV et j'ai besoin de l'importer dans une table en SQL 2005 ou 2008. Les noms de colonne et le compte dans le CSV sont différents des noms de colonne de table et comptent. Le CSV est divisé par un ';' .
Exemple
CSV FileContents:
FirstName;LastName;Country;Age
Roger;Mouthout;Belgium;55
Table de personne SQL
Columns: FName,LName,Country
La solution
Je créerais une table temporaire, j'inserterais le lot, je sélectionnerais dans la nouvelle table ce dont vous avez besoin et déposez la table temporaire.
Quelque chose comme
CREATE TABLE dbo.TempImport
(
FirstName varchar(255),
LastName varchar(255),
Country varchar(255),
Age varchar(255)
)
GO
BULK INSERT dbo.TempImport FROM 'PathToMyTextFile' WITH (FIELDTERMINATOR = ';', ROWTERMINATOR = '\n')
GO
INSERT INTO dbo.ExistingTable
(
FName,
LName,
Country
)
SELECT FirstName,
LastName,
Country
FROM dbo.TempImport
GO
DROP TABLE dbo.TempImport
GO
Autres conseils
Vous pouvez utiliser un fichier de format lors de l'importation avec BCP:
Créez un fichier de format pour votre table:
bcp [table_name] format nul -f [format_file_name.fmt] -c -T
9.0
4
1 SQLCHAR 0 100 "," 1 FName SQL_Latin1_General_CP1_CI_AS
2 SQLCHAR 0 100 "," 2 LName SQL_Latin1_General_CP1_CI_AS
3 SQLCHAR 0 100 "," 3 Country SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 100 "\r\n" 0 Age SQL_Latin1_General_CP1_CI_AS
Modifier le fichier d'importation. L'astuce consiste à ajouter une ligne factice pour le champ que vous souhaitez sauter et à ajouter un «0» comme commande de colonne de serveur.
Importez ensuite les données à l'aide de ce fichier de format, en spécifiant votre fichier d'entrée, ce fichier de format et le séparateur:
bcp [table_name] in [data_file_name] -t , -f [format_file_name.fmt] -T
Je préfère maintenant utiliser des fichiers de format XML comme celui-ci avec un insert en vrac ou OpenRowset:
<?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="1" xsi:type="CharTerm" TERMINATOR="|" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="37"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="41"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="|" MAX_LENGTH="17"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="10" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="i" xsi:type="SQLCHAR"/>
<COLUMN SOURCE="2" NAME="j" xsi:type="SQLUNIQUEID"/>
<COLUMN SOURCE="3" NAME="k" xsi:type="SQLNUMERIC" PRECISION="18" SCALE="0"/>
<COLUMN SOURCE="4" NAME="l" xsi:type="SQLBINARY"/>
<COLUMN SOURCE="5" NAME="m" xsi:type="SQLVARYCHAR"/>
</ROW>
</BCPFORMAT>
Ensuite, vous pouvez utiliser la commande d'insert en vrac côté serveur comme suit:
BULK INSERT foo FROM '\\mydomain.com\bar\bletch' WITH (FORMATFILE='foo.xml', ERRORFILE='foo.errors', FIRSTROW = 1, BATCHSIZE=10000)
Alternativement, si vous souhaitez modifier les données «en vol», vous pouvez utiliser le
INSERT foo(i, j,k)
SELECT foo_delimited.i, foo_delimited.j, foo_delimited.k * 2
OPENROWSET(BULK 'foo',
FORMATFILE= 'foo.xml')
AS foo_delimited
Pour plus d'informations, avec la même structure, vous pouvez utiliser ce type de déclaration:
bcp schema.Table in "/Samples/AdventureWorksDW/DimCurrency.csv" \
-S db.url \
-d databaseName \
-U userName \
-P pwd \
-t ; `# The field separator ` \
-c `# Insert as character and doesn't ask the data type` \
-q `# With quote -- seems to be mandatory`
Voir Exemple