SSIS XML 无类型任务 XML
SSIS XML Task with Untyped XML
我对从 XML 数据源加载数据到 SQL 服务器还很陌生,但我过去曾成功地使用格式正确的 XML 数据源。我有一个 Web 服务,该服务正在通过第三方解决方案的 SSIS 调用以获取数据。此 Web 服务吐出如下数据:
<?xml version="1.0" encoding="utf-16"?>
<EpsTableEx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ErrorString />
<ErrorNum>1</ErrorNum>
<Data>
<ArrayOfString>
<string>ObjectId</string>
<string>Form_Type</string>
<string>Owner</string>
<string>CompletedDate</string>
<string>Delivered</string>
<string>Name</string>
<string>EventID</string>
</ArrayOfString>
<ArrayOfString>
<string>183122</string>
<string>Form1</string>
<string>91b</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21966</string>
</ArrayOfString>
<ArrayOfString>
<string>183152</string>
<string>Form1</string>
<string>2879d</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21967</string>
</ArrayOfString>
</Data>
</EpsTableEx>
第一个 ArrayOfString 是 header 列,而不是每个元素都是 header.
列
在另一个具有正确格式的 XML 网络服务的包中,我正在使用 XML 任务编辑器通过 XPATH 操作深入到数据级别,这对我不起作用这里。这导致 ArrayOfString 和 String 被剥离,所有数据连接在一起。
我试过:
- 将 XPATH 操作更改为 XML 路径的不同级别但没有成功。
- 改变 XSD 文件试图强制它认为 ArrayOfString 标记中的文本将是要插入到 table 中的文本,然后稍后解析它,但没有数据通过.
- 更改 XSD 文件,使定义的字段具有 String1、String2 等,希望它将映射到每个项目的通用字符串标签。
我正在使用 SQL Server 2014 和 Data Tools 构建 SSIS 包。
编辑:
目标是在 SSIS 中有一个解决方案,可以 运行 每晚。
编辑2:
数据将被加载到 table 中,如下所示:
CREATE TABLE [dbo].[FormXML](
[ObjectID] [nvarchar](255) NULL,
[Form_Type] [nvarchar](255) NULL,
[Owner] [nvarchar](255) NULL,
[CompletedDate] [nvarchar](255) NULL,
[Delivered] [nvarchar](255) NULL,
[Name] [nvarchar](255) NULL,
[EventID] [nvarchar](255) NULL,
[ADD_DTTM] [datetime] NULL DEFAULT (getdate()))
我不关心 ErrorString 或 ErrorNum 节点。我修改了建议的 XML 查询以使用执行 SQL 任务将数据插入 table。
在 SSIS 中放入变量的 XML 是 +400k 个字符。我在网上看到,根据这篇文章 (http://www.sqlservercentral.com/articles/SQL+Server/97947/),字符串变量有 2GB 的限制。我怀疑这是我的问题,如果我可以将 XML 从 Web 服务加载到 XML 变量而不是字符串变量中,我就不会遇到这个问题。
假设这个 XML 携带一个带有数据行的 "table" 我建议不要从第一个块中获取列名。他们可能是"hard coded":
只需将其粘贴到一个空的 SQL 查询 window 中并执行。根据您的需要进行调整...
declare @x XML='<EpsTableEx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ErrorString />
<ErrorNum>1</ErrorNum>
<Data>
<ArrayOfString>
<string>ObjectId</string>
<string>Form_Type</string>
<string>Owner</string>
<string>CompletedDate</string>
<string>Delivered</string>
<string>Name</string>
<string>EventID</string>
</ArrayOfString>
<ArrayOfString>
<string>183122</string>
<string>Form1</string>
<string>91b</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21966</string>
</ArrayOfString>
<ArrayOfString>
<string>183152</string>
<string>Form1</string>
<string>2879d</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21967</string>
</ArrayOfString>
</Data>
</EpsTableEx>';
SELECT ArrayOfString.block.value('string[1]','int') AS ObjectId
,ArrayOfString.block.value('string[2]','varchar(max)') AS Form_Type
,ArrayOfString.block.value('string[3]','varchar(max)') AS [Owner]
,ArrayOfString.block.value('string[4]','date') AS CompletedDated
,ArrayOfString.block.value('string[5]','date') AS Delivered
,ArrayOfString.block.value('string[6]','varchar(max)') AS [Name]
,ArrayOfString.block.value('string[7]','int') AS EventID
FROM @x.nodes('/EpsTableEx/Data/ArrayOfString[position()>1]') AS ArrayOfString(block)
我使用 2 个不同的变量解决了这个问题。我将 Web 服务的 XML 输出输入到一个字符串变量中,我们称它为 String1
。然后我创建了另一个变量,称为 String2
,并创建了一个表达式来将 String1
格式化为可用的 XML 字符串。
我下面的表达式替换了“\n”、“\r”和“xmlns=\”http://Eprise\“”的所有实例,以正确设置字符串格式。然后我使用 SUBSTRING 表达式只获取数据标签中字符串的移植。 FINDSTRING 位于数据标记开始的位置,LEN 帮助找到字符串的实际长度。
replace(
replace(
replace(
substring(@[User::String1],
FINDSTRING( @[User::String1] , "<Data", 1) ,
LEN(
substring(@[User::String1],
FINDSTRING( @[User::String1] ,
"<Data",
1),
LEN(@[User::String1])
)
) -13
)
,"\n","")
,"\r","")
," xmlns=\"http://Eprise\"","")
我必须在 String1
中填充一个至少 13 个字符的初始值,以便我可以 trim 结束 String1
以删除最后一个结束标记。我还需要初始值来包含文本“String2 to evaluate to true initially.
格式化 String2
后,我使用并执行 SQL 任务。我添加了一个参数,使用 String2
作为 NVARCHAR 类型的输入方向,名称为 0,长度为 2147483647,即 2 gb,SSIS 中字符串的最大值。
我将 SQL 查询从 @Shnugo 调整为:
declare @x as xml
set @x=?
insert into Database.dbo.Table ([ObjectID] ,[Form_Type],[Owner],[CompletedDate],[Delivered],[Name],[EventID])
SELECT block.value('string[1]', 'varchar(max)') AS ObjectId
,block.value('string[2]', 'varchar(max)') AS Form_Type
,block.value('string[3]', 'varchar(max)') AS OWNER
,block.value('string[4]', 'varchar(max)') AS CompletedDated
,block.value('string[5]', 'varchar(max)') AS Delivered
,block.value('string[6]', 'varchar(max)') AS NAME
,block.value('string[7]', 'varchar(max)') AS EventID
FROM @x.nodes('/Data/ArrayOfString[position()>1]') AS ArrayOfString(block)
那个?从我格式化的 XML 字符串参数中提取值,然后使用 XML 查询将数据插入 table。
我对从 XML 数据源加载数据到 SQL 服务器还很陌生,但我过去曾成功地使用格式正确的 XML 数据源。我有一个 Web 服务,该服务正在通过第三方解决方案的 SSIS 调用以获取数据。此 Web 服务吐出如下数据:
<?xml version="1.0" encoding="utf-16"?>
<EpsTableEx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ErrorString />
<ErrorNum>1</ErrorNum>
<Data>
<ArrayOfString>
<string>ObjectId</string>
<string>Form_Type</string>
<string>Owner</string>
<string>CompletedDate</string>
<string>Delivered</string>
<string>Name</string>
<string>EventID</string>
</ArrayOfString>
<ArrayOfString>
<string>183122</string>
<string>Form1</string>
<string>91b</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21966</string>
</ArrayOfString>
<ArrayOfString>
<string>183152</string>
<string>Form1</string>
<string>2879d</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21967</string>
</ArrayOfString>
</Data>
</EpsTableEx>
第一个 ArrayOfString 是 header 列,而不是每个元素都是 header.
列在另一个具有正确格式的 XML 网络服务的包中,我正在使用 XML 任务编辑器通过 XPATH 操作深入到数据级别,这对我不起作用这里。这导致 ArrayOfString 和 String 被剥离,所有数据连接在一起。
我试过:
- 将 XPATH 操作更改为 XML 路径的不同级别但没有成功。
- 改变 XSD 文件试图强制它认为 ArrayOfString 标记中的文本将是要插入到 table 中的文本,然后稍后解析它,但没有数据通过.
- 更改 XSD 文件,使定义的字段具有 String1、String2 等,希望它将映射到每个项目的通用字符串标签。
我正在使用 SQL Server 2014 和 Data Tools 构建 SSIS 包。
编辑: 目标是在 SSIS 中有一个解决方案,可以 运行 每晚。
编辑2: 数据将被加载到 table 中,如下所示:
CREATE TABLE [dbo].[FormXML](
[ObjectID] [nvarchar](255) NULL,
[Form_Type] [nvarchar](255) NULL,
[Owner] [nvarchar](255) NULL,
[CompletedDate] [nvarchar](255) NULL,
[Delivered] [nvarchar](255) NULL,
[Name] [nvarchar](255) NULL,
[EventID] [nvarchar](255) NULL,
[ADD_DTTM] [datetime] NULL DEFAULT (getdate()))
我不关心 ErrorString 或 ErrorNum 节点。我修改了建议的 XML 查询以使用执行 SQL 任务将数据插入 table。
在 SSIS 中放入变量的 XML 是 +400k 个字符。我在网上看到,根据这篇文章 (http://www.sqlservercentral.com/articles/SQL+Server/97947/),字符串变量有 2GB 的限制。我怀疑这是我的问题,如果我可以将 XML 从 Web 服务加载到 XML 变量而不是字符串变量中,我就不会遇到这个问题。
假设这个 XML 携带一个带有数据行的 "table" 我建议不要从第一个块中获取列名。他们可能是"hard coded":
只需将其粘贴到一个空的 SQL 查询 window 中并执行。根据您的需要进行调整...
declare @x XML='<EpsTableEx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ErrorString />
<ErrorNum>1</ErrorNum>
<Data>
<ArrayOfString>
<string>ObjectId</string>
<string>Form_Type</string>
<string>Owner</string>
<string>CompletedDate</string>
<string>Delivered</string>
<string>Name</string>
<string>EventID</string>
</ArrayOfString>
<ArrayOfString>
<string>183122</string>
<string>Form1</string>
<string>91b</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21966</string>
</ArrayOfString>
<ArrayOfString>
<string>183152</string>
<string>Form1</string>
<string>2879d</string>
<string>2015-03-02</string>
<string>2015-04-22</string>
<string>Onboarding</string>
<string>21967</string>
</ArrayOfString>
</Data>
</EpsTableEx>';
SELECT ArrayOfString.block.value('string[1]','int') AS ObjectId
,ArrayOfString.block.value('string[2]','varchar(max)') AS Form_Type
,ArrayOfString.block.value('string[3]','varchar(max)') AS [Owner]
,ArrayOfString.block.value('string[4]','date') AS CompletedDated
,ArrayOfString.block.value('string[5]','date') AS Delivered
,ArrayOfString.block.value('string[6]','varchar(max)') AS [Name]
,ArrayOfString.block.value('string[7]','int') AS EventID
FROM @x.nodes('/EpsTableEx/Data/ArrayOfString[position()>1]') AS ArrayOfString(block)
我使用 2 个不同的变量解决了这个问题。我将 Web 服务的 XML 输出输入到一个字符串变量中,我们称它为 String1
。然后我创建了另一个变量,称为 String2
,并创建了一个表达式来将 String1
格式化为可用的 XML 字符串。
我下面的表达式替换了“\n”、“\r”和“xmlns=\”http://Eprise\“”的所有实例,以正确设置字符串格式。然后我使用 SUBSTRING 表达式只获取数据标签中字符串的移植。 FINDSTRING 位于数据标记开始的位置,LEN 帮助找到字符串的实际长度。
replace(
replace(
replace(
substring(@[User::String1],
FINDSTRING( @[User::String1] , "<Data", 1) ,
LEN(
substring(@[User::String1],
FINDSTRING( @[User::String1] ,
"<Data",
1),
LEN(@[User::String1])
)
) -13
)
,"\n","")
,"\r","")
," xmlns=\"http://Eprise\"","")
我必须在 String1
中填充一个至少 13 个字符的初始值,以便我可以 trim 结束 String1
以删除最后一个结束标记。我还需要初始值来包含文本“String2 to evaluate to true initially.
格式化 String2
后,我使用并执行 SQL 任务。我添加了一个参数,使用 String2
作为 NVARCHAR 类型的输入方向,名称为 0,长度为 2147483647,即 2 gb,SSIS 中字符串的最大值。
我将 SQL 查询从 @Shnugo 调整为:
declare @x as xml
set @x=?
insert into Database.dbo.Table ([ObjectID] ,[Form_Type],[Owner],[CompletedDate],[Delivered],[Name],[EventID])
SELECT block.value('string[1]', 'varchar(max)') AS ObjectId
,block.value('string[2]', 'varchar(max)') AS Form_Type
,block.value('string[3]', 'varchar(max)') AS OWNER
,block.value('string[4]', 'varchar(max)') AS CompletedDated
,block.value('string[5]', 'varchar(max)') AS Delivered
,block.value('string[6]', 'varchar(max)') AS NAME
,block.value('string[7]', 'varchar(max)') AS EventID
FROM @x.nodes('/Data/ArrayOfString[position()>1]') AS ArrayOfString(block)
那个?从我格式化的 XML 字符串参数中提取值,然后使用 XML 查询将数据插入 table。