批量插入格式文件不跳过目标 table 中的列,应有 146 个字段

Bulk Insert with format file NOT skipping column in destination table with 146 fields as it should be

这是完整的错误:

消息 4864,级别 16,状态 1,第 3 行 第 1 行第 5 列 (FK_User_CreatedBy) 的批量加载数据转换错误(指定代码页的类型不匹配或无效字符)。

这是我痛苦的现存快照:)

很多问题都涉及到这些问题,but none of them do the trick...

我怀疑我的问题与 here 中描述的类似,但我不确定。未被正确跳过的目标 table 列不是稀疏的。

这是在记事本和记事本++中打开的用于导入的两行数据文件(.csv): (是的,我知道行终止符是 \r\n 而 field/column 终止符是 \t 或 ',')

这里是纯文本:

1,fArty,Padul,1,10/1/1962,Head of ,Australia,AU Talavera Centre,NSW,7 CSU,farty.randy@gummibaer.com
2,mifsm,Jodel,1,10/1/1970,Chief Officer,Australia,AU ,NSW,8 CSU,midsm@gummibaer.com

CONTEXT/BACKGROUND: 测试小型 Table 和具有少量记录的输入文件(请记住它是在 table 上跳过列,最终会造成伤害)...

导入非常适合小型数据库 table,如下所示:

并且是这样创建的:

这是 table 创建的代码:

    DROP TABLE dbo.tbl_Person_Importtest

CREATE TABLE dbo.tbl_Person_Importtest 
(
ID int PRIMARY KEY NOT NULL,
LastName varchar(100) NOT NULL, 
FirstName varchar(100) NOT NULL, 
FK_Gender varchar(4) NOT NULL, 
DateOfBirth date NOT NULL, 
JobTitle varchar(200) NOT NULL, 
Address1Country varchar(50) NOT NULL, 
Location varchar(200) NOT NULL,
Address1StateOrProvince varchar(50) NOT NULL, 
Department varchar(200) NOT NULL, 
EMailAddress1  varchar(200) NOT NULL
)  

.xml 批量插入格式文件如下所示:

请注意,如果我跳过 ID (PK + 索引) 列,它也会起作用,因为数据库 table 是空的并且导入文件没有索引。这对于小目标 table 工作正常,因为数据库正在生成主键索引。

此处格式文件为文本():

<?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="CharTerm" TERMINATOR="\t" MAX_LENGTH="12"/>
  <FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="100" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="100" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="4" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="5" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="11"/>
  <FIELD ID="6" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="200" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="7" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="50" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="8" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="200" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="9" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="50" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="10" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="200" COLLATION="Latin1_General_CI_AS"/>
  <FIELD ID="11" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="200" COLLATION="Latin1_General_CI_AS"/>
 </RECORD>
 <ROW>
  <COLUMN SOURCE="1" NAME="ID" xsi:type="SQLINT"/>
  <COLUMN SOURCE="2" NAME="LastName" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="3" NAME="FirstName" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="4" NAME="FK_Gender" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="5" NAME="DateOfBirth" xsi:type="SQLDATE"/>
  <COLUMN SOURCE="6" NAME="JobTitle" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="7" NAME="Address1Country" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="8" NAME="Location" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="9" NAME="Address1StateOrProvince" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="10" NAME="Department" xsi:type="SQLVARYCHAR"/>
  <COLUMN SOURCE="11" NAME="EMailAddress1" xsi:type="SQLVARYCHAR"/>
 </ROW>
</BCPFORMAT>

它是在命令行中使用 bcp 创建的,如下所示:

这里是文本中的 bcp 命令行:

bcp YFP..tbl_Person_Importtest 格式 nul -f PersonImportMapFile.xml -c -x -T

现在,当我对空的小 table 执行所有这些文件的导入时,一切都很好:

如果我再次插入更多行,没问题...

大 TABLE 由于知识 属性 问题,我无法包含完整描述,但大目的地 table 有 146 个字段没有稀疏字段和大量 DATETIME 和 DATE 字段,以及外键堆栈(主要是 INT),其中一些可以为 null。这是由 bcp 生成的映射文件(字段名称被截断并删除了一些):

   CREATE TABLE [dbo].[tbl_Person](
[ID] [int] IDENTITY(1,1) NOT NULL,
[RecordTitle] [nvarchar](250) NULL,
[SecurityCode] [nvarchar](250) NULL,
[DateCreated] [smalldatetime] NOT NULL,
[FK_User_CreatedBy] [int] NULL,
[wning] [int] NULL,
[ssigned] [int] NULL,
[ollowup] [int] NULL,
[sation_Owning] [int] NULL,
[wning] [int] NULL,
[pdate] [smalldatetime] NULL,
[astUpdate] [int] NULL,
[tatus] [bit] NULL,
[ive] [smalldatetime] NULL,
[eason] [nvarchar](250) NULL,
[tatus] [bit] NULL,
[ion] [smalldatetime] NULL,
[Titles] [int] NULL,
[LastName] [varchar](50) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[MiddleName] [nvarchar](50) NULL,
[DateOfBirth] [datetime] NULL,
[ion] [ntext] NULL,
[Code] [nvarchar](50) NULL,
[r] [int] NULL,
[] [nvarchar](100) NULL,
[nt] [nvarchar](100) NULL,
[ame] [nvarchar](100) NULL,
[hone] [nvarchar](50) NULL,
[tName] [nvarchar](100) NULL,
[e1] [nvarchar](50) NULL,
[e2] [nvarchar](50) NULL,
[one1] [nvarchar](50) NULL,
[Moe2] [nvarchar](50) NULL,
[Fax] [nvarchar](50) NULL,
[e1] [nvarchar](250) NULL,
[e2] [nvarchar](250) NULL,
[e3] [nvarchar](250) NULL,
[Address1CityOrSuburb] [nvarchar](50) NULL,
[Address1StateOrProvince] [nvarchar](50) NULL,
[Address1Country] [nvarchar](50) NULL,
[Address1PostalCode] [nvarchar](20) NULL,
[Line1] [nvarchar](250) NULL,
[Line2] [nvarchar](250) NULL,
[Line3] [nvarchar](250) NULL,
[CityOrSuburb] [nvarchar](50) NULL,
[StateOrProvince] [nvarchar](50) NULL,
[Country] [nvarchar](50) NULL,
[PostalCode] [nvarchar](20) NULL,
[RL] [nvarchar](200) NULL,
[ress1] [nvarchar](100) NULL,
[ress2] [nvarchar](100) NULL,
[ne] [bit] NULL,
[] [bit] NULL,
[il] [bit] NULL,
[tail] [bit] NULL,
[kEl] [bit] NULL,
[kPalMail] [bit] NULL,
[dMM] [bit] NULL,
[_Preferred] [int] NULL,
[] [int] NULL,
[onStatus] [int] NULL,
[1] [money] NULL,
[2] [money] NULL,
[3] [money] NULL,
[4] [money] NULL,
[5] [money] NULL,
[6] [money] NULL,
[ncome] [money] NULL,
[rInc1] [money] NULL,
[rInc2] [money] NULL,
[rInc3] [money] NULL,
[rInc4] [money] NULL,
[rInc5] [money] NULL,
[rInc6] [money] NULL,
[artner] [money] NULL,
[1] [money] NULL,
[2] [money] NULL,
[3] [money] NULL,
[4] [money] NULL,
[5] [money] NULL,
[6] [money] NULL,
[7] [money] NULL,
[8] [money] NULL,
[ud] [money] NULL,
[] [money] NULL,
[] [money] NULL,
[] [money] NULL,
[] [money] NULL,
[] [money] NULL,
[] [money] NULL,
[lAss] [money] NULL,
[1] [money] NULL,
[2] [money] NULL,
[3] [money] NULL,
[4] [money] NULL,
[5] [money] NULL,
[lDebt] [money] NULL,
[rganisation_Provider] [int] NULL,
[Insurance] [money] NULL,
[ver] [money] NULL,
[itd] [nvarchar](250) NULL,
[veod] [nvarchar](250) NULL,
[fiNominated] [bit] NULL,
[ [money] NULL,
[idD] [nvarchar](50) NULL,
[ccs] [int] NULL,
[mpus] [int] NULL,
[ry] [money] NULL,
[feInsurance] [bit] NULL,
[Cor] [bit] NULL,
[ov] [money] NULL,
[DCer] [bit] NULL,
[mous] [int] NULL,
[iftatus] [int] NULL,
[PCos] [int] NULL,
[PDCus] [int] NULL,
[ersned] [int] NULL,
[ueKey] [uniqueidentifier] NULL,
[rified] [bit] NULL,
[Actr] [smalldatetime] NULL,
[embpe] [int] NULL,
[etAult] [money] NULL,
[t7] [money] NULL,
[t8] [money] NULL,
[6] [money] NULL,
[7] [money] NULL,
[8] [money] NULL,
[onalScore] [nvarchar](10) NULL,
[] [int] NULL,
[rganment] [int] NULL,
[rac] [int] NULL,
[kerpdate] [datetime] NULL,
[keriew] [datetime] NULL,
[ari] [int] NULL,
[] [int] NULL,
[Q1] [int] NULL,
[Q2] [int] NULL,
[Q3] [int] NULL,
[Q4] [int] NULL,
[Q5] [int] NULL,
[Q6] [int] NULL,
[Q7] [int] NULL,
[Q8] [int] NULL,
[Q9] [int] NULL,
[Q10] [int] NULL,
 CONSTRAINT [PK_tbl_Person] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

结果

我应该能够使用我为上面较小的 table 示例指定的相同数据文件导入此 table,但我收到了开头指定的错误这个问题。

它选择的字段确实是 table 中的第五个 field/column,但根据 [=27=,它应该只跳到地图中指定的字段].

看起来我需要使用暂存 table 或其他带有中间件或 SQLBulkCopy (c# .NET) 的编程方法,我不想在这个阶段这样做。我只希望地图文件可以工作。

我是不是错过了什么,或者是用-map-file for-large-table马拍摄BULK INSERT并获得不同的骑行?

对于您的情况,列数不是 bcp 问题。

最可能的原因是数据类型不匹配或 FK 问题。

用于调试。

取消对 table

的限制

创建 table 的副本(select * 从 table 复制到 temptable,其中 1=2)

使用-e选项对temptable执行BCP,如果错误文件中有记录则为数据类型/格式问题。

如果数据是在 temptable 中复制的,则检查所有约束,如 fk、ak....

您可能错过的是教程中使用 XML 格式文件跳过列的示例将数据插入到仅包含目标列的视图中;似乎无法使用 XML 格式文件来跳过目标 table.

中的列

您可以在 tbl_person 上创建相关列的视图并插入其中。

或者,您可以使用旧式非 XML 格式的文件,或者(如果您的环境安全设置允许,可能更容易)使用 OPENROWSET(BULK...) - 这些选项都包含在教程.

您可能会考虑更改其他一些内容:

1 - 示例范围 table 定义在几个方面与您的输入文件不匹配:

  • 您的文件中没有 NOT NULLDateCreated 的来源 - 您可能需要 DEFAULT 约束来设置值 - 也许存在但在示例 table 定义?
  • table 不包含 FK_GenderJobTitleLocationDepartmentEMailAddress1 列,即使它们被引用格式文件 - 这可能是您编辑列名称的副作用。

2 - 您可以使用如下命令生成与数据文件更匹配的格式文件,该命令将字段终止符正确设置为逗号:

bcp YFP..tbl_Person_Importtest format nul -f c:\temp\so.bcp.gen.test.fmt -c -x -T -t ,

3 - 您的 BULK INSERT 命令的屏幕截图包括命令:

SET IDENTITY INSERT <table> OFF

在批量插入之前。这有两个问题:

  • 这在 BULK INSERT 命令的上下文中没有任何作用,您将在其中使用 KEEPIDENTITY 选项。

  • 设置 IDENTITY INSERT OFF 禁用标识值的插入(即正常行为)。如果使用 OPENROWSET(BULK...) 方法,则需要在命令运行之前设置 IDENTITY INSERT ON 以启用标识插入,然后在命令完成后设置 IDENTITY INSERT OFF