我从客户端获取 CSV,我需要将该文件导入数据库。我经历了无数次迭代,部分解决方案测试无穷大。当我需要完整的解决方案时,我的问题就来了。
CSV 有 14 个字段,tempdb 数据库有 15 个字段(最后一个是标识列)。数据到达时没有身份,我需要根据数据库设计的行唯一编号。
我已经掩盖了显示的测试数据,但它可以模拟数据。
T2012-DAT;09-01-2012;09-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 T2012-DAT;10-01-2012;10-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 T2012-DAT;11-01-2012;11-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 T2012-DAT;12-01-2012;12-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5 T2012-DAT;13-01-2012;13-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7 T2012-DAT;16-01-2012;16-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5
我在 tempdb 中创建的临时表。您会注意到它有 15 个字段,最后一个是所需的身份。
创建表预算导入( sBudgetName varchar(20) COLLATE Danish_Norwegian_CI_AS , dStartDate varchar(12) COLLATE Danish_Norwegian_CI_AS , dEndDate varchar(12) COLLATE Danish_Norwegian_CI_AS , prCode 整数 , decTotal varchar(20) COLLATE Danish_Norwegian_CI_AS , sRefTimeTypeID varchar(10) COLLATE Danish_Norwegian_CI_AS , sRefEmployeeID varchar(10) COLLATE Danish_Norwegian_CI_AS , decHours varchar(20) COLLATE Danish_Norwegian_CI_AS , decRate varchar(20) COLLATE Danish_Norwegian_CI_AS , sDepartmentID varchar(10) COLLATE Danish_Norwegian_CI_AS NULL , sCentre varchar(10) 整理丹麦语_挪威语_CI_AS NULL , 目的 varchar(10) COLLATE Danish_Norwegian_CI_AS NULL , sProjectID varchar(10) COLLATE Danish_Norwegian_CI_AS NULL , decNormHours varchar(20) COLLATE Danish_Norwegian_CI_AS --, iRowNumber int identity(500000,1) )
去
-- 通过 csv 导入数据 批量插入 BudgetImport FROM 'D:\budgetposter.csv' 和 ( 场终结者 = ';' , 行终止符 = '\r\n' , 代码页 = '1252' )
当我包含身份时,我收到此错误:
消息 4866,第 16 层,状态 1,第 3 行 批量加载失败。数据文件中第 1 行第 15 列的列太长。请验证是否正确指定了字段终止符和行终止符。
如果我排除它,错误将变为:
消息 4866,第 16 层,状态 1,第 3 行 批量加载失败。数据文件中第 1 行第 14 列的列太长。验证是否正确指定了字段终止符和行终止符。
如果我改变rowterminator = '\n'
它,它会通过,但我错过了身份。
如果我包括身份,则错误变为:
消息 4864,第 16 层,状态 1,第 3 行 第 1 行第 15 列 (iRowNumber) 的批量加载数据转换错误(指定代码页的类型不匹配或无效字符)。
当我测试时,我排除了INSERT INTO dbo."the-real-datatable"
并且只是SELECT FROM BudgetImport
单独做。因此,我避免在真实数据表中插入另外 16000 行。
如果您注意并了解匈牙利符号,您会注意到我使用的是 varchars,即使 datatime 或 decimal 可能是正确的形式。经过大约 4-6 小时的测试和无尽的头痛和撕裂的头发后,我正在这样做。Varchar 是 KISS 解决方案,我CONVERT()
稍后再做。
我的整个问题围绕行中的最后一个字段解决。- 我尝试添加 1 和 2 ;在 decNormHours 之后,我尝试添加空值(;;或;1;或;n;)。- 我尝试过使用 formatfile.xml - 再次没有蛋糕。没有格式文件比使用它更成功。- 我尝试将英国数字符号更改为 . = 使用 DK 表示法更成功。- 我已经尝试了我能想出的每一个技巧,但无济于事。
是的,CSV 中没有身份字段,没关系。identity(500000,1)
您只需使用我在表创建中描述的默认自动。哦,500000 是我现在达到的大约行 ID,它会随着时间的推移而增加。
拜托,接下来我需要做什么才能做到这一点?
编辑:
使用格式文件
$lt;? xml 版本=“1.0”?$gt; $lt;BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"$gt; $lt;记录$gt; FIELD ID="1" xsi:type="NCharTerm" TERMINATOR=";" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="2" xsi:type="CharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="3" xsi:type="CharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="4" xsi:type="NCharTerm" TERMINATOR=";"/ FIELD ID="5" xsi:type="NCharTerm" TERMINATOR=";"/ FIELD ID="6" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="7" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="8" xsi:type="NCharTerm" TERMINATOR=";"/ FIELD ID="9" xsi:type="NCharTerm" TERMINATOR=";"/ FIELD ID="10" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="11" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="12" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="13" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/ FIELD ID="14" xsi:type="NCharTerm" TERMINATOR=";"/ /记录 排 COLUMN SOURCE="1" NAME="sBudgetName" xsi:type="SQLNVARCHAR" LENGTH="20" / COLUMN SOURCE="2" NAME="dStartDate" xsi:type="SQLDATETIME"/ COLUMN SOURCE="3" NAME="dEndDate" xsi:type="SQLDATETIME"/ COLUMN SOURCE="4" NAME="prCode" xsi:type="SQLSMALLINT"/ COLUMN SOURCE="5" NAME="decTotal" xsi:type="SQLDECIMAL"/ COLUMN SOURCE="6" NAME="sRefTimeTypeID" xsi:type="SQLNVARCHAR" LENGTH="10"/ COLUMN SOURCE="7" NAME="sRefEmployeeID" xsi:type="SQLNVARCHAR" LENGTH="10"/ COLUMN SOURCE="8" NAME="decHours" xsi:type="SQLDECIMAL"/ COLUMN SOURCE="9" NAME="decRate" xsi:type="SQLDECIMAL"/ COLUMN SOURCE="10" NAME="sDepartmentID" xsi:type="SQLNVARCHAR" LENGTH="10"/ COLUMN SOURCE="11" NAME="中心" xsi:type="SQLNVARCHAR" LENGTH="10"/ COLUMN SOURCE="12" NAME="Purpose" xsi:type="SQLNVARCHAR" LENGTH="10"/ COLUMN SOURCE="13" NAME="sRefProjectID" xsi:type="SQLNVARCHAR" LENGTH="10"/ COLUMN SOURCE="14" NAME="decNormHours" xsi:type="SQLDECIMAL"/ /排
让我回到正确的第一个领域。因此,从争取最终的细节正确开始,我最终会努力让它首先工作/做任何事情。错误:
消息 4863,第 16 层,状态 1,第 3 行 第 1 行第 1 列 (sBudgetName) 的批量加载数据转换错误(截断)。
注意:嗯似乎 SO 不喜欢 xml。多么奇怪。