Sql 使用格式化文件在数据文件和实际数据库表之间进行大容量插入,以改变列数

Sql 使用格式化文件在数据文件和实际数据库表之间进行大容量插入,以改变列数,sql,sql-server,tsql,bulkinsert,bcp,Sql,Sql Server,Tsql,Bulkinsert,Bcp,这是表的模式 Create table dbo.Project ( ProjectID (int,not null) ManagerID (int,not null) CompanyID(int, not null) Title (nvarchar(50),not null) StartDate(datetime,not null) EndDate(datetime,null) ProjDescription(nvarchar(max)) ) 我使用下面的bcp命令从这个表中创建了一个名为bo

这是表的模式

Create table dbo.Project
(
ProjectID (int,not null)
ManagerID (int,not null)
CompanyID(int, not null)
Title (nvarchar(50),not null)
StartDate(datetime,not null)
EndDate(datetime,null)
ProjDescription(nvarchar(max))
)
我使用下面的bcp命令从这个表中创建了一个名为bob.dat的数据文件,它大约有15行

bcp "Select ProjectID,ManagerID,CompanyID,Title,StartDate from CATS.dbo.Project" queryout "C:\Documents\bob.dat" -Sbob-pc -T -n 
bcp CATS.dbo.Project format nul -f C:\Documents\bob.fmt -x -Sbob-pc -T -n 
此外,还使用以下bcp命令创建了名为bob.fmt的格式/映射文件

bcp "Select ProjectID,ManagerID,CompanyID,Title,StartDate from CATS.dbo.Project" queryout "C:\Documents\bob.dat" -Sbob-pc -T -n 
bcp CATS.dbo.Project format nul -f C:\Documents\bob.fmt -x -Sbob-pc -T -n 
然后我创建了表项目的一个副本

Create table dbo.ProjectCopy
(
ProjectID (int,not null)
ManagerID (int,not null)
CompanyID(int, not null)
Title (nvarchar(50),not null)
StartDate(datetime,not null)
EndDate(datetime,null)
ProjDescription(nvarchar(max))
)

我现在要做的是使用bob.dat和bob.format文件,使用下面的大容量插入语句填充这个表ProjectCopy

BULK INSERT CATS.dbo.ProjectCopy
 FROM 'C:\Documents\bob.dat' 
WITH (FORMATFILE = 'C:\Documents\bob.fmt',
 LASTROW=5,
 KEEPNULLS,
  DATAFILETYPE='native');
  GO
 SELECT * FROM CATS.dbo.ProjectCopy
 GO
 Msg 4863, Level 16, State 4, Line 2
 Bulk load data conversion error (truncation) for row 1, column 6 (EndDate).
 Msg 7399, Level 16, State 1, Line 2
 The OLE DB provider "BULK" for linked server "(null)" reported an error. 
 The provider did not give any information about the error.
 Msg 7330, Level 16, State 2, Line 2
 Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".

 (0 row(s) affected)
因此,数据文件基本上不包含EndDate和ProjDescription列的任何数据。我希望这两列保持为空。不幸的是,我得到了 运行大容量insert语句时出现以下错误

BULK INSERT CATS.dbo.ProjectCopy
 FROM 'C:\Documents\bob.dat' 
WITH (FORMATFILE = 'C:\Documents\bob.fmt',
 LASTROW=5,
 KEEPNULLS,
  DATAFILETYPE='native');
  GO
 SELECT * FROM CATS.dbo.ProjectCopy
 GO
 Msg 4863, Level 16, State 4, Line 2
 Bulk load data conversion error (truncation) for row 1, column 6 (EndDate).
 Msg 7399, Level 16, State 1, Line 2
 The OLE DB provider "BULK" for linked server "(null)" reported an error. 
 The provider did not give any information about the error.
 Msg 7330, Level 16, State 2, Line 2
 Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".

 (0 row(s) affected)
有人知道怎么解决这个问题吗? 我只是想告诉大家,我已经到过这一部分,以及那里提供的解决方案 不适合我。 , ,

首先,要创建名为bob.dat的数据文件,需要添加两列:EndDate和ProjDescription。此外,对于使用Unicode字符的批量复制操作,必须添加参数-W。 例如:

原始格式文件:

<?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="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="2" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="3" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="4" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="100" COLLATION="Cyrillic_General_CI_AS"/>
  <FIELD ID="5" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="48"/>
  <FIELD ID="6" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="48"/>
  <FIELD ID="7" xsi:type="NCharTerm" TERMINATOR="\r\0\n\0" COLLATION="Cyrillic_General_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ProjectID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="ManagerID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="3" NAME="CompanyID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="Title" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="StartDate" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="6" NAME="EndDate" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="7" NAME="ProjDescription" xsi:type="SQLNVARCHAR"/>
 </ROW>
</BCPFORMAT>

但是,您需要一种只在开始日期之前填充数据的方法。因此,需要更改此文件:

<?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="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="2" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="3" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="4" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="100" COLLATION="Cyrillic_General_CI_AS"/>
  <FIELD ID="5" xsi:type="NCharTerm" TERMINATOR="\r\0\n\0" MAX_LENGTH="48"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ProjectID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="ManagerID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="3" NAME="CompanyID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="Title" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="StartDate" xsi:type="SQLDATETIME"/>
 </ROW>
</BCPFORMAT>

首先,要创建名为bob.dat的数据文件,需要添加两列:EndDate和ProjDescription。此外,对于使用Unicode字符的批量复制操作,必须添加参数-W。 例如:

原始格式文件:

<?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="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="2" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="3" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="4" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="100" COLLATION="Cyrillic_General_CI_AS"/>
  <FIELD ID="5" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="48"/>
  <FIELD ID="6" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="48"/>
  <FIELD ID="7" xsi:type="NCharTerm" TERMINATOR="\r\0\n\0" COLLATION="Cyrillic_General_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ProjectID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="ManagerID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="3" NAME="CompanyID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="Title" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="StartDate" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="6" NAME="EndDate" xsi:type="SQLDATETIME"/>
  <COLUMN SOURCE="7" NAME="ProjDescription" xsi:type="SQLNVARCHAR"/>
 </ROW>
</BCPFORMAT>

但是,您需要一种只在开始日期之前填充数据的方法。因此,需要更改此文件:

<?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="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="2" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="3" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="24"/>
  <FIELD ID="4" xsi:type="NCharTerm" TERMINATOR="\t\0" MAX_LENGTH="100" COLLATION="Cyrillic_General_CI_AS"/>
  <FIELD ID="5" xsi:type="NCharTerm" TERMINATOR="\r\0\n\0" MAX_LENGTH="48"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ProjectID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="ManagerID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="3" NAME="CompanyID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="4" NAME="Title" xsi:type="SQLNVARCHAR"/>
  <COLUMN SOURCE="5" NAME="StartDate" xsi:type="SQLDATETIME"/>
 </ROW>
</BCPFORMAT>


列中的EndDate不允许为空值。尝试更改NULLHi上的notnull!谢谢:)。我将其更改为Null,但仍会收到相同的错误。在SSIS或.net应用程序中处理此错误会更为得体。我通常使用streamreader,在字段不可用时添加null。蒂姆·米切尔(Tim Mitchell)为那些没有.net经验的人提供了一个很好的选择:很棒的链接。非常感谢brian:)列中的EndDate不允许为空值。尝试更改NULLHi上的notnull!谢谢:)。我将其更改为Null,但仍会收到相同的错误。在SSIS或.net应用程序中处理此错误会更为得体。我通常使用streamreader,在字段不可用时添加null。蒂姆·米切尔(Tim Mitchell)为那些没有.net经验的人提供了一个很好的选择:很棒的链接。非常感谢brian:)是的,我知道如果我在数据文件中添加EndDate和ProjDescription的数据,它就会工作。这是经过考验的。不过,我希望通过省略最后两列使流程更加灵活。如果你知道一种只将数据填充到起始日期的方法,那就太棒了。想一想,将来可能会有额外的列添加到表中,在这种情况下,是否可以使用相同的数据和格式文件?@Sike12确定。答案是用新信息更新的,请阅读我以前尝试过的内容。使用您的格式文件时,我收到以下错误消息。Msg 7339,级别16,状态1,链接服务器的第3行OLE DB提供程序“BULK”(null)“为列“[BULK].StartDate”返回了无效数据。”。(受影响的0行)创建数据文件需要使用-w参数:bcp“从CATS.dbo.Project“queryyout”C:\Users\Pawan\Documents\bob.dat”-Sbob pc-T-n-wOh中选择projectd、ManagerID、CompanyID、Title、StartDate、ProjDescription。对不起,这是个打字错误。bcp“从CATS.dbo.Project“queryout”C:\Users\Pawan\Documents\bob.dat”-Sbob pc-T-n-wyes中选择projectd、ManagerID、CompanyID、Title、StartDate,我知道如果我在数据文件中添加EndDate和ProjDescription的数据,它就会工作。这是经过考验的。不过,我希望通过省略最后两列使流程更加灵活。如果你知道一种只将数据填充到起始日期的方法,那就太棒了。想一想,将来可能会有额外的列添加到表中,在这种情况下,是否可以使用相同的数据和格式文件?@Sike12确定。答案是用新信息更新的,请阅读我以前尝试过的内容。使用您的格式文件时,我收到以下错误消息。Msg 7339,级别16,状态1,链接服务器的第3行OLE DB提供程序“BULK”(null)“为列“[BULK].StartDate”返回了无效数据。”。(受影响的0行)创建数据文件需要使用-w参数:bcp“从CATS.dbo.Project“queryyout”C:\Users\Pawan\Documents\bob.dat”-Sbob pc-T-n-wOh中选择projectd、ManagerID、CompanyID、Title、StartDate、ProjDescription。对不起,这是个打字错误。bcp“从CATS.dbo.Project“queryout”C:\Users\Pawan\Documents\bob.dat”中选择ProjectID、ManagerID、CompanyID、Title、StartDate