如何在 SQL Standard 上导出 SSIS 数据并在 SQL Express 上使用 Bulk Insert 导入?
Posted
技术标签:
【中文标题】如何在 SQL Standard 上导出 SSIS 数据并在 SQL Express 上使用 Bulk Insert 导入?【英文标题】:How to Export SSIS data on SQL Standard and Import with Bulk Insert on SQL Express? 【发布时间】:2009-04-09 16:23:37 【问题描述】:我想使用 SSIS 创建数据库表平面文件导出,然后将它们导入到各种分布式 SQL Express 安装中。正如您可能猜到的,SSIS 在 Express 版本中不可用。当我进行批量插入时,它会出错:
Msg 4866, Level 16, State 8, Line 1
The bulk load failed. The column is too long in the data file for row 1, column 5. Verify that the field terminator and row terminator are specified correctly.
生成的文件是 ascii (1252),字段之间有 char(09) (tab),char(0d) char(0a) 结束一行(我认为是 \r\n)。
这是格式文件(第 4 列是列的宽度):
9.0
5
1 SQLCHAR 0 12 "\t" 1 Record_ID ""
2 SQLCHAR 0 498 "\t" 2 Filename SQL Latin1 General CP1 CI AS
3 SQLCHAR 0 498 "\t" 3 Path SQL Latin1 General CP1 CI AS
4 SQLCHAR 0 12 "\t" 4 Width ""
5 SQLCHAR 0 12 "\r\n" 5 Height ""
从文件顶部开始的示例数据:
Record_ID Filename Path Width Height
1437 BreadCakeCooknPie.eps G:\BakedGoods\BreadCakeCooknPie.eps 595 647
1438 CakeChocolateRoses.eps G:\BakedGoods\CakeChocolateRoses.eps 1200 848
我使用以下 T-SQL 代码导入它:
bulk insert item_table from 'Item_Table.txt' with
( FORMATFILE='Item_Table.fmt', FIRSTROW=2)
表格字段是:
[Record_ID] [int] NULL,
[Filename] [nvarchar](249) NULL,
[Path] [nvarchar](249) NOT NULL,
[Width] [int] NULL,
[Height] [int] NULL
有没有可用的文章?知道如何解决错误吗?知道如何获取 SSIS 创建的格式文件吗?还有其他想法吗?
非常感谢您考虑我的问题。
【问题讨论】:
【参考方案1】:这是否在数据流的源部分失败?您可以发布与源相关的元数据吗?我偶尔发现 SSIS 无法正确估计平面文件连接上的大小或数据类型。发生这种情况时,数据流任务将在导入的源部分遇到超过该位置预期的平面文件连接长度的数据。
这是否在数据流的目标部分失败?如果是这样,如果您使用数据读取器作为目标而不是实际的目标表,它至少可以工作吗?我猜你的问题是在管道的早期,但如果它超过了数据流的源部分,那么你至少可以将问题隔离为目标问题。
请让我们知道它在数据流中的实际中断位置。
【讨论】:
当我从查询窗口执行“批量插入”时,它会中断。 SSIS 中没有任何内容显示任何错误。奇怪的是,如果我使用 BCP 将表转储到磁盘,包括格式文件,然后尝试将其批量插入回来,它会失败并出现同样的错误。 我还尝试导出表中的所有字段,因为 SP1 2005 SQL 存在一个错误,即 bcp 和批量插入失败,格式文件指定的字段少于目标表。我还检查了所有元数据都不是 unicode。 您的回答使我重新制作了所有元数据,这使我找到了解决方案,如下所列。【参考方案2】:您是否考虑过以竖线或逗号分隔格式运行 SSIS 导出?在导出和导入之间处理制表符的方式可能存在问题。
您在此处列出的所有内容似乎都没有指向 SSIS 或批量插入的问题,只是文件本身的格式问题。
【讨论】:
我尝试将制表符切换为管道,将 eol 切换为分号。它抱怨该字段的数据太长。我用相同的答案尝试了 Unicode 和 1252。似乎问题在于将文本文件中存储为 10 个字符的 INT 转换为 4 字节的 int 字段可能吗? 嗯,这相当令人困惑。我建议保持行终止符 (eol) 与以前相同 (\r\n)。看看有没有帮助。【参考方案3】:这是部分答案。显然,您可以从 BCP 开始,让它生成一个格式文件和一个文本数据转储,使用来自 bcp 的格式文件并在 SSIS 中完全匹配文本导出。数据文件中的物理字段排列(即使您可以在格式文件中对其进行排序)和没有丢失的字段(即使您不需要它们)似乎是关键。
我必须手动使文本导出元数据与格式文件匹配(在文本文件连接管理器的列下手动键入元数据)。这导致文本文件中字段的物理顺序与表中的物理顺序相匹配(我之前使用格式文件列来匹配这些,这似乎不起作用)。
从 SSIS 导出的内容仍然不一样,但足够接近可以导入。例如,当 bcp 导出数据时,它会将 .000 放在日期字段后面,将 .0 放在数字字段(浮点数等)后面。
我的最终格式文件如下。请注意,所有字段都是 SQLCHAR,即使有些是 unicode,所有大小都是错误的(int 是 10,但它有 12),(文本长度为 249,但它有 498),以及(我必须将所有字段放入,而不仅仅是我要导入的那些。它没有正确跳过字段。)
疯狂的世界。任何想法为什么会这样?
9.0
29
1 SQLCHAR 0 12 "\t" 1 Record_ID ""
2 SQLCHAR 0 498 "\t" 2 Filename SQL_Latin1_General_CP1_CI_AS
3 SQLCHAR 0 498 "\t" 3 Path SQL_Latin1_General_CP1_CI_AS
4 SQLCHAR 0 498 "\t" 4 Extension_Win SQL_Latin1_General_CP1_CI_AS
5 SQLCHAR 0 498 "\t" 5 Short_Filename_Win SQL_Latin1_General_CP1_CI_AS
6 SQLCHAR 0 498 "\t" 6 Volume SQL_Latin1_General_CP1_CI_AS
7 SQLCHAR 0 24 "\t" 7 Created ""
8 SQLCHAR 0 24 "\t" 8 Last_Modified ""
9 SQLCHAR 0 24 "\t" 9 Cataloged ""
10 SQLCHAR 0 24 "\t" 10 Last_Updated ""
11 SQLCHAR 0 12 "\t" 11 File_Size ""
12 SQLCHAR 0 498 "\t" 12 Mac_File_Type SQL_Latin1_General_CP1_CI_AS
13 SQLCHAR 0 498 "\t" 13 Mac_Creator SQL_Latin1_General_CP1_CI_AS
14 SQLCHAR 0 498 "\t" 14 Mac_Zone SQL_Latin1_General_CP1_CI_AS
@ 987654337@16 SQLCHAR 0 12 "\t" 16 Color_Mode ""
17 SQLCHAR 0 30 "\t" 17 Horizontal_Resolution ""
18 SQLCHAR 0 30 "\t" 18 Vertical_Resolution ""
19 SQLCHAR 0 12 "\t" 19 Width ""
20 SQLCHAR 0 12 "\t" 20 Height ""
21 SQLCHAR 0 12 "\t" 21 MultipageCount ""
22 SQLCHAR 0 12 "\t" 22 PlaceHolder ""
23 SQLCHAR 0 12 "\t" 23 Watermarked ""
24 SQLCHAR 0 12 "\t" 24 FileStoreID ""
25 SQLCHAR 0 498 "\t" 25 Directory_Path SQL_Latin1_General_CP1_CI_AS
26 SQLCHAR 0 12 "\t" 26 RID ""
27 SQLCHAR 0 498 "\t" 27 Cataloged_By SQL_Latin1_General_CP1_CI_AS
28 SQLCHAR 0 498 "\t" 28 Updated_By SQL_Latin1_General_CP1_CI_AS
29 SQLCHAR 0 0 "\r\n" 29 File_Description SQL_Latin1_General_CP1_CI_AS
【讨论】:
虽然不是一个好的答案:使用命令行 bcp 我导出格式文件和实际数据。我设置 SSIS 文本文件列(第 3 个选项卡)与格式文件完全一样。然后,我设置 SSIS 元数据以匹配 BCP 导出的数据。一切都很好地导入,一些数据被截断,比如日期的秒数。以上是关于如何在 SQL Standard 上导出 SSIS 数据并在 SQL Express 上使用 Bulk Insert 导入?的主要内容,如果未能解决你的问题,请参考以下文章
SQL 导出到平面文件比作业中 SSIS 中的相同导出运行得更快