我很擅长将数据从XML数据源加载到SQL Server中,但过去我已经成功使用了格式正确的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是列标题,而不是每个元素都是列标题。
在另一个包含格式正确的XML Web服务的包中,我使用XML任务编辑器通过XPATH操作进入数据级别,这对我来说不起作用。这导致ArrayOfString和String被剥离,并且所有数据被连接在一起。
我试过了:
我正在使用SQL Server 2014和数据工具来构建SSIS包。
修改: 目标是在SSIS中建立一个可以每晚运行的解决方案。
EDIT2: 数据将加载到如下表格中:
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任务将数据插入表中。
在SSIS中放入变量的XML是+ 400k字符。我在网上读到根据这篇文章(http://www.sqlservercentral.com/articles/SQL+Server/97947/)对字符串变量有2GB的限制。我怀疑这是我的问题,如果我可以将XML从Web服务加载到XML变量而不是字符串变量,我就不会遇到这个问题。
答案 0 :(得分:1)
假设这个XML带有一个包含数据行的“表”,我建议不要从第一个块中获取列名。它们可能是“硬编码”的:
只需将其粘贴到一个空的SQL查询窗口并执行即可。根据您的需求进行调整......
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)
答案 1 :(得分:0)
我用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个字符的初始值,以便我可以修剪String1
的结尾以删除最后一个结束标记。我还需要初始值来包含文本“String2以最初评估为真。
格式化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 String参数中提取值,然后使用XML Query将数据插入表中。