web-dev-qa-db-ja.com

SQL Serverに正しく引用符で囲まれたCSVファイルを一括挿入

正しく引用符で囲まれたCSVファイルをインポートしようとしています。つまり、データにカンマが含まれている場合のみ引用されます。

41, Terminator, Black
42, "Monsters, Inc.", Blue

最初の行は正しくインポートされますが、2行目は引用符で囲まれたコンマがフィールド区切り記号として扱われることを示唆する方法でエラーが発生します。

このような提案を見てきました

CSVからのSQL一括インポート

フィールドターミネータを変更するには

FIELDTERMINATOR = '"、"'

ただし、CSVファイルはそれを必要とするフィールドのみを引用しているため、提案が機能するとは思わない。

SQL ServerのBULK IMPORTステートメントは、正しく引用されたCSVファイルをインポートできますか?どうやって?

47
Eric J.

残念ながら、SQL Serverは引用符で囲まれたコンマを区切り文字として解釈します。これは、BCPと一括挿入の両方に適用されます。

から http://msdn.Microsoft.com/en-us/library/ms191485%28v=sql.100%29.aspx

ターミネーター文字がデータ内で発生した場合、データとしてではなくターミネーターとして解釈され、その文字の後のデータは次のフィールドまたはレコードに属するものとして解釈されます。したがって、ターミネータを慎重に選択して、データに表示されないようにしてください。

28
iruvar

これには別の解決策があります。

Fmtファイルを編集して、フィールド区切り文字の一部として引用符を検討します。

詳細については、これを確認できます。

http://blogs.msdn.com/b/sqlserverfaq/archive/2010/02/04/how-to-remove-unwanted-quotation-marks-while-importing-a-data-file.aspx

上記のリンクの抜粋:

引用符を削除する唯一の方法は、インポート操作中に指定された列区切り文字を変更することです。ここでの唯一の欠点は、挿入するデータを調べると、列区切り文字が列ごとに異なることにすぐに気付くということです(上記の強調表示された区切り文字)。

そのため、列ごとに異なる列区切り文字を指定するには、一括挿入またはBCPを使用する予定がある場合にフォーマットファイルを使用する必要があります。上記のテーブル構造のフォーマットファイルを生成する場合、次のようになります。

9.0
3
1       SQLCHAR       0       5       "\t"     1     FName              SQL_Latin1_General_CP1_CI_AS
2       SQLCHAR       0       5       "\t"     2     LName              SQL_Latin1_General_CP1_CI_AS
3       SQLCHAR       0       50      "\r\n"   3     Company            SQL_Latin1_General_CP1_CI_AS

各列の正しい列区切り文字を表すようにフォーマットファイルを変更します。使用される新しいフォーマットファイルは次のようになります。

9.0
4
1       SQLCHAR       0       0     "\""      0     FIRST_QUOTE      SQL_Latin1_General_CP1_CI_AS
2       SQLCHAR       0       5     "\",\""   1     FNAME               SQL_Latin1_General_CP1_CI_AS
3       SQLCHAR       0       5     "\",\""   2     LNAME            SQL_Latin1_General_CP1_CI_AS
4       SQLCHAR       0       50    "\"\r\n"  3     COMPANY          SQL_Latin1_General_CP1_CI_AS
18
Rafael Segovia

これは古いトピックですが、この機能はSQL Server 2017以降に実装されています。探しているパラメーターはFIELDQUOTE =で、デフォルトは '"'です。詳細は https://docs.Microsoft .com/en-us/sql/t-sql/statements/bulk-insert-transact-sql?view = sql-server-2017

12
Dominix

TextQualifiedオプションが有効になっていることを確認し、"

8
Bangxin

これと同じ問題があり、SSISルートに行く必要はありませんでした。そのため、実行しやすく、特定のフィールドにカンマが含まれる引用符のケースを処理するPowerShellスクリプトを見つけました。

ソースコードとDLL: https://github.com/billgraziano/CsvDataReader

使用方法を説明するブログは次のとおりです。 http://www.sqlteam.com/article/fast-csv-import-in-powershell-to-sql-server

4
sloppyjoe

CSVテキストファイルデータプロバイダーでOpenRowSetを使用することもできます。

これは、SQL Server 2005以降のすべてのバージョンで可能になりますが、機能を有効にする必要があります。

http://social.msdn.Microsoft.com/forums/en-US/sqldataaccess/thread/5869d247-f0a0-4224-80b3-ff2e414be402

3

私は同じ問題を抱えていました。一部のテキストをたまに二重引用符で囲むデータのみです。私の解決策は、BULK LOADに二重引用符をインポートさせ、インポートされたデータに対してREPLACEを実行することです。

例えば:

「FIRSTROW = 1、FIELDTERMINATOR = '、'、ROWTERMINATOR = '\ n');で「F:\ Data\Map\CodePointOpen\Data\CSV\ab.csv」からCodePoint_tblを一括挿入します。

更新CodePoint_tbl set Postcode = replace(Postcode、 '"'、 '')where charindex( '"'、Postcode)> 0

REPLACEスクリプトの作成を簡単にするには、次のような結果から必要なものをコピーして貼り付けてください。

select C.ColID, C.[name] as Columnname into #Columns
from syscolumns C
join sysobjects T on C.id = T.id
where T.[name] = 'User_tbl'
order by 1;

declare @QUOTE char(1);
set @QUOTE = Char(39);
select 'Update User_tbl set '+ColumnName+'=replace('+ColumnName+','
 + @QUOTE + '"' + @QUOTE + ',' + @QUOTE + @QUOTE + ');
GO'
from #Columns
where ColID > 2
order by ColID;
2
Keith MacDonald

私はこの問題に半日費やしました。 SQL Serverのデータのインポートおよびエクスポートウィザードを使用してインポートすることをお勧めします。この問題を解決する設定がウィザードにあります。詳細なスクリーンショットはこちら: https://www.mssqltips.com/sqlservertip/1316/strip-double-quotes-from-an-import-file-in-integration-services-ssis/ ありがとう

2
mye.morr

CSV形式仕様ごとに、仕様に準拠している限り、データが正しく引用されているかどうかは問題ではないと思います。適切に実装されている場合、過剰な引用符はパーサーで処理する必要があります。 FIELDTERMINATORはコンマで、ROWTERMINATORは行末です-これは標準CSVファイルを示します。これらの設定でデータをインポートしようとしましたか?

0
Neolisk