BULK INSERT与标识(自动递增)列BULK INSERT与标识(自动递增)列(BULK IN

2019-05-16 21:57发布

我试图从CSV文件中的数据库中添加大量的数据。

Employee表中有一列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)。

Answer 1:

不要BULK INSERT到你的真实的表直接。

我总是

  1. 插入到一个临时dbo.Employee_Staging (不IDENTITY从CSV文件列)
  2. 可能是编辑/整理/操控导入的数据
  3. 然后将数据传达给了T-SQL语句像真正的表复制:

     INSERT INTO dbo.Employee(Name, Address) SELECT Name, Address FROM dbo.Employee_Staging 


Answer 2:

一个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标识字段会自动递增。

如果您在CSV赋值给id字段,它们将被忽略,除非你使用KEEPIDENTITY关键字,那么他们就会被用来代替自动递增。



Answer 3:

我也有类似的问题,但我需要确保该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');


Answer 4:

你所要做的使用格式文件进行批量插入:

   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个地址SQL_Latin1_General_CP1_CI_AS

这里更多的细节- http://msdn.microsoft.com/en-us/library/ms179250.aspx



Answer 5:

我的解决方案是将ID字段添加如表中的LAST字段,从而大容量插入忽略它和它得到自动的值。 清洁和简单...

例如,如果插入到一个临时表:

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

需要注意的是ROW_ID场必须指定为最后字段!



Answer 6:

另一种选择,如果你正在使用临时表,而不是临时表,可以创建临时表作为进口预期,则在导入后添加标识列。

所以,你的SQL确实是这样的:

  1. 如果临时表存在,降
  2. 创建临时表
  3. 批量导入到临时表
  4. 改变临时表的附加身份
  5. <任何你想要的数据做>
  6. 降临时表

仍然不是很干净,但它是另一种选择......可能获得的锁是安全的了。



Answer 7:

我有这使得损失小时所以我启发,分享我的发现和对我工作的解决方案这一相同问题。

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中,你的数据库,然后选择导入数据(在任务子菜单)上右键单击您的数据库。 选择Microsoft Excel作为源。 当你在叫阶段到达“选择源表和视图”,然后单击编辑映射 。 对于id在目标栏中,单击它并选择忽略 。 不检查Enable Identity insert ,除非你想十个分量,你是从另一个数据库导入数据,并想保持源数据库的自动增量ID IDS incases。 继续完成,仅此而已。 您的数据能够顺利进口。

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文件和Microsoft SQL Server Management Studio中导入选项

启动您的进口数据就像在第一种方法。 对于源,选择平面文件源和浏览您的CSV文件。 确保右键菜单(通用,列,高级预览)都OK。 请务必在设置菜单栏(列分隔符)右分隔符。 就像上面的Excel的方法,单击编辑映射 。 对于在目的地ID列,单击它并选择忽略

继续完成,仅此而已。 您的数据能够顺利进口。



Answer 8:

  1. 创建标识列+其他列的表;
  2. 在它创建一个视图,仅露出列你会批量插入;
  3. BCP视图


Answer 9:

这是一个很旧的文章来回答,但没有给出答案的问题解决了在不改变所带来的条件下,我不能这样做。

我使用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”与列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>

现在,我们可以批量通过不将数据插入到标识列中的数据文件加载到我们的桌子有一个选择,因此具有完全控制研究在列,在这种情况下:

INSERT INTO target_table (col1,col2, col3)
SELECT * FROM  openrowset(
bulk 'C:\data_file.txt',
formatfile='C:\format_file.xml') as t;


文章来源: BULK INSERT with identity (auto-increment) column