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)の一括読み込みデータ変換エラー(指定されたコードページの型の不一致または無効な文字)。
realテーブルに直接INSERTしないでください。
私はいつも
dbo.Employee_Staging
(IDENTITY
列なし)に挿入します次のようなT-SQLステートメントを使用して、データを実際のテーブルにコピーします。
INSERT INTO dbo.Employee(Name, Address)
SELECT Name, Address
FROM dbo.Employee_Staging
Id列をcsvファイルに追加し、空白のままにします。
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');
Id IDフィールドは自動インクリメントされます。
Csvのidフィールドに値を割り当てた場合、KEEPIDENTITYキーワードを使用しない限り無視され、自動インクリメントの代わりに使用されます。
同様の問題がありましたが、IDの順序がソースファイルの順序と一致していることを確認する必要がありました。私の解決策は、一括挿入にビューを使用しています:
テーブルをそのままにして、このビューを作成します(ID列を除くすべてを選択します)
CREATE VIEW [dbo].[VW_Employee]
AS
SELECT [Name], [Address]
FROM [dbo].[Employee];
BULK INSERTは次のようになります。
BULK INSERT [dbo].[VW_Employee] FROM 'path\tempFile.csv '
WITH (FIRSTROW = 2,FIELDTERMINATOR = ',' , ROWTERMINATOR = '\n');
フォーマットファイルで一括挿入を行う必要があります。
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_AS
2 SQLCHAR 0 50 "\ r\n" 3 Address SQL_Latin1_General_CP1_CI_AS
詳細はこちら- http://msdn.Microsoft.com/en-us/library/ms179250.aspx
私の解決策は、IDフィールドをテーブルのLASTフィールドとして追加することです。したがって、一括挿入はそれを無視し、自動値を取得します。清潔でシンプルな...
たとえば、一時テーブルに挿入する場合:
CREATE TABLE #TempTable
(field1 varchar(max), field2 varchar(max), ...
ROW_ID int IDENTITY(1,1) NOT NULL)
ROW_ID
フィールドは常にLASTフィールドとして指定しなければならないことに注意してください!
私はこのまったく同じ問題を抱えていたため、損失時間が発生したので、自分に合った発見と解決策を共有したいと思います。
1。Excelファイルを使用
これが私が採用したアプローチです。 csvファイルを使用する代わりに、以下のような内容のExcelファイル(.xlsx)を使用しました。
id username email token website
johndoe [email protected] divostar.com
bobstone [email protected] divosays.com
Id列には値がないことに注意してください。
次に、Microsoft SQL Server Management Studioを使用してDBに接続し、データベースを右クリックしてインポートデータを選択します(タスクの下のサブメニュー)。ソースとしてMicrosoft Excelを選択します。 「ソーステーブルとビューの選択」というステージに到達したら、マッピングの編集をクリックします。宛先の下のid
列については、それをクリックしてignoreを選択します。別のデータベースからデータをインポートする場合にIDを保持し、ソースDBの自動インクリメントIDを維持したい場合を除き、Enable Identity insert
をチェックしないでください。仕上げに進み、それで終わりです。データはスムーズにインポートされます。
2。CSVファイルを使用
Csvファイルで、データが以下のようになっていることを確認してください。
id,username,email,token,website
,johndoe,[email protected],,divostar.com
,bobstone,[email protected],,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をそのサーバーのディレクトリにアップロードし、一括挿入でパスを参照できます。
。CSVファイルとMicrosoft SQL Server Management Studioインポートオプションを使用
最初のアプローチのようにインポートデータを起動します。ソースについては、フラットファイルソースを選択し、CSVファイルを参照します。正しいメニュー([全般]、[列]、[詳細]、[プレビュー])に問題がないことを確認してください。列メニュー(列区切り文字)で正しい区切り文字を設定してください。上記のExcelのアプローチと同様に、マッピングの編集をクリックします。宛先の下のid列については、それをクリックしてignoreを選択します。
仕上げに進み、それで終わりです。データはスムーズにインポートされます。
別のオプションは、ステージングテーブルの代わりに一時テーブルを使用している場合、インポートが期待するとおりに一時テーブルを作成し、インポート後にID列を追加することです。
だからあなたのSQLは次のようなことをします:
まだあまりきれいではありませんが、別のオプションです...安全のためにロックを取得する必要があるかもしれません。
これは非常に古い答えの投稿ですが、与えられた答えのいずれも、提起された条件を変更せずに問題を解決するものではありません。
BULK INSERTの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"およびCOLUMN SOURCE = "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;