78

CSVファイルからデータベースにバルクデータを追加しようとしています。

従業員テーブルには、ID自動インクリメントされた列(PK)があります。

CREATE TABLE [dbo].[Employee](
 [id] [int] IDENTITY(1,1) NOT NULL,
 [Name] [varchar](50) NULL,
 [Address] [varchar](50) NULL
) ON [PRIMARY]

私はこのクエリを使用しています:

BULK INSERT Employee  FROM 'path\tempFile.csv ' 
WITH (FIRSTROW = 2,KEEPIDENTITY,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');

.CSVファイル-

Name,Address
name1,addr test 1
name2,addr test 2

ただし、次のエラーメッセージが表示されます。

行2、列1(id)のバルクロードデータ変換エラー(指定されたコードページのタイプの不一致または無効な文字)。

4

9 に答える 9

106

csvファイルにid列を追加し、空白のままにします。

id,Name,Address
,name1,addr test 1
,name2,addr test 2

クエリからKEEPIDENTITYキーワードを削除します。

BULK INSERT Employee  FROM 'path\tempFile.csv ' 
WITH (FIRSTROW = 2,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');

IDIDフィールドは自動インクリメントされます。

csvのidフィールドに値を割り当てると、KEEPIDENTITYキーワードを使用しない限り無視され、自動インクリメントの代わりに使用されます。

于 2012-09-12T20:22:15.820 に答える
55

実際のテーブルに直接一括挿入しないでください。

私はいつも

  1. CSVファイルからステージングテーブルdbo.Employee_Staging(列なし)に挿入しますIDENTITY
  2. インポートしたデータを編集/クリーンアップ/操作する可能性があります
  3. 次に、次のようなT-SQLステートメントを使用して、データを実際のテーブルにコピーします。

    INSERT INTO dbo.Employee(Name, Address) 
       SELECT Name, Address
       FROM dbo.Employee_Staging
    
于 2012-06-01T13:24:02.357 に答える
38

同様の問題が発生しましたが、IDの順序がソースファイルの順序と一致していることを確認する必要がありました。私の解決策は、BULKINSERTにVIEWを使用することです。

テーブルをそのままにして、このビューを作成します(ID列を除くすべてを選択します)

CREATE VIEW [dbo].[VW_Employee]
AS
SELECT [Name], [Address]
FROM [dbo].[Employee];

バルクインサートは次のようになります。

BULK INSERT [dbo].[VW_Employee] FROM 'path\tempFile.csv ' 
WITH (FIRSTROW = 2,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');
于 2014-04-25T13:51:06.503 に答える
9

フォーマットファイルを使用して一括挿入を行う必要があります。

   BULK INSERT Employee FROM 'path\tempFile.csv ' 
   WITH (FORMATFILE = 'path\tempFile.fmt');

ここで、フォーマットファイル(tempFile.fmt)は次のようになります。

11.0
2
1 SQLCHAR 0 50 "\t"2名前SQL_Latin1_General_CP1_CI_AS2SQLCHAR
0 50 "\ r \n"3アドレスSQL_Latin1_General_CP1_CI_AS

詳細はこちら-http://msdn.microsoft.com/en-us/library/ms179250.aspx

于 2014-07-27T07:32:10.977 に答える
2

私の解決策は、IDフィールドをテーブルのLASTフィールドとして追加することです。したがって、一括挿入はそれを無視し、自動値を取得します。清潔でシンプル...

たとえば、一時テーブルに挿入する場合:

CREATE TABLE #TempTable 
(field1 varchar(max), field2 varchar(max), ... 
ROW_ID int IDENTITY(1,1) NOT NULL)

ROW_IDフィールドは常にLASTフィールドとして指定する必要があることに注意してください。

于 2016-04-04T10:16:02.807 に答える
2
  1. Identity列+他の列を持つテーブルを作成します。
  2. その上にビューを作成し、一括挿入する列のみを公開します。
  3. ビューのBCP
于 2018-10-16T15:37:01.090 に答える
1

私はこれとまったく同じ問題を抱えていたため、損失時間が発生したため、自分の調査結果と解決策を共有することになりました。

1.Excelファイルを使用する

これが私が採用したアプローチです。csvファイルを使用する代わりに、以下のような内容のExcelファイル(.xlsx)を使用しました。

id  username   email                token website

    johndoe   johndoe@divostar.com        divostar.com
    bobstone  bobstone@divosays.com        divosays.com

id列には値がないことに注意してください。

次に、Microsoft SQL Server Management Studioを使用してDBに接続し、データベースを右クリックして、[データのインポート]を選択します(タスクの下のサブメニュー)。ソースとしてMicrosoftExcelを選択します。「ソーステーブルとビューの選択」という段階に到達したら、[マッピングの編集]をクリックします。宛先の下のid列で、それをクリックして無視を選択します。Enable Identity insert別のデータベースからデータをインポートしていて、ソースデータベースの自動インクリメントIDを維持したい場合に備えて、IDを維持したい場合を除いて、チェックしないでください。終了に進み、それだけです。データはスムーズにインポートされます。

2.CSVファイルを使用する

csvファイルで、データが次のようになっていることを確認してください。

id,username,email,token,website
,johndoe,johndoe@divostar.com,,divostar.com
,bobstone,bobstone@divosays.com,,divosays.com

以下のクエリを実行します。

BULK INSERT Metrics FROM 'D:\Data Management\Data\CSV2\Production Data 2004 - 2016.csv '
WITH (FIRSTROW = 2, FIELDTERMINATOR = ',', ROWTERMINATOR = '\n');

このアプローチの問題は、CSVがDBサーバーまたはDBがアクセスできる共有フォルダーにある必要があることです。そうしないと、「ファイルを開けません。オペレーティングシステムがエラーコード21を返しました(デバイスの準備ができていません)」などのエラーが発生する可能性があります。 )」。

リモートデータベースに接続している場合は、CSVをそのサーバー上のディレクトリにアップロードし、一括挿入でパスを参照できます。

3.CSVファイルとMicrosoftSQLServerManagementStudioのインポートオプションを使用する

最初のアプローチと同様に、インポートデータを起動します。ソースについては、フラットファイルソースを選択し、CSVファイルを参照します。正しいメニュー([一般]、[列]、[詳細]、[プレビュー])に問題がないことを確認してください。列メニュー(列区切り文字)で正しい区切り文字を設定してください。上記のExcelアプローチと同様に、[マッピングの編集]をクリックします。宛先の下のid列で、それをクリックして[無視]を選択します。

終了に進み、それだけです。データはスムーズにインポートされます。

于 2016-11-18T13:35:01.863 に答える
1

これは答えるのに非常に古い投稿ですが、与えられた答えのどれも、私ができない、提起された条件を変更せずに問題を解決することはできません。

BULKINSERTのOPENROWSETバリアントを使用して解決しました。これは同じフォーマットファイルを使用し、同じように機能しますが、SELECTステートメントでデータファイルを読み取ることができます。

テーブルを作成します。

CREATE TABLE target_table(
id bigint IDENTITY(1,1),
col1 varchar(256) NULL,
col2 varchar(256) NULL,
col3 varchar(256) NULL)

コマンドウィンドウを開いて実行します。

bcp dbname.dbo.target_table format nul -c -x -f C:\format_file.xml -t; -T

これにより、テーブルの外観に基づいてフォーマットファイルが作成されます。

次に、フォーマットファイルを編集し、FIELD ID="1"とCOLUMNSOURCE= "1"の行全体を削除します。これは、データファイルに存在しないためです。
また、データファイルに必要なターミネータを調整します。

<?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="2" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="256" COLLATION="Finnish_Swedish_CI_AS"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="256" COLLATION="Finnish_Swedish_CI_AS"/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="256" COLLATION="Finnish_Swedish_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="2" NAME="col1" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="col2" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="4" NAME="col3" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

これで、selectを使用してデータファイルをテーブルに一括ロードできるため、この場合はID列にデータを挿入しないことで、列を完全に制御できます。

INSERT INTO target_table (col1,col2, col3)
SELECT * FROM  openrowset(
bulk 'C:\data_file.txt',
formatfile='C:\format_file.xml') as t;
于 2019-02-05T17:45:23.293 に答える
0

ステージングテーブルの代わりに一時テーブルを使用している場合の別のオプションは、インポートが期待するとおりに一時テーブルを作成し、インポート後にID列を追加することです。

したがって、SQLは次のようになります。

  1. 一時テーブルが存在する場合は、ドロップします
  2. 一時テーブルを作成する
  3. 一時テーブルへの一括インポート
  4. 一時テーブルの変更IDの追加
  5. <データでやりたいことは何でも>
  6. 一時テーブルを削除します

まだあまりきれいではありませんが、それは別のオプションです...安全のためにロックを取得する必要があるかもしれません。

于 2015-11-17T11:54:51.167 に答える