从 SSIS 中的对象变量生成带有自定义标记的 XML 文件
Generate XML File with custom tag from Object Variable in SSIS
我正在尝试使用 SSIS 从 sql table 数据中生成带有自定义标签和属性的 XML 文件。
我编写了从对象变量写入数据的 C# 脚本,但它给我一个错误“对象不是 ADODB.RecordSet 或 ADODB.Record。参数名称:adodb”。
请帮忙。
提前致谢
您可以直接从 MSSQL 输出 xml 而无需使用 SSIS,您可以使用列别名来设置您的自定义 tags/attributes。
请看下面的演示,属性用@前缀别名,标签没有任何前缀,子标签用/
构建
使用子查询构建多行子标签
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestParent
(
ParentId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentAttribute1 VARCHAR(50),
ParentAttribute2 VARCHAR(50),
ParentValue VARCHAR(50)
)
INSERT INTO #WhosebugTestParent VALUES ('Oh','Hello','World')
INSERT INTO #WhosebugTestParent VALUES ('World','Goes','Hello')
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestChild
(
ChildId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentId BIGINT,
ChildAttribute1 VARCHAR(50),
ChildAttribute2 VARCHAR(50),
ChildValue VARCHAR(50)
)
INSERT INTO #WhosebugTestChild VALUES (1,'Bobby','Says','Hello')
INSERT INTO #WhosebugTestChild VALUES (1,'Dobby','Starts','Waving')
INSERT INTO #WhosebugTestChild VALUES (2,'Dolly','Says','Hozit')
INSERT INTO #WhosebugTestChild VALUES (2,'Sarah','Says','Hi')
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestParent
(
ParentId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentAttribute1 VARCHAR(50),
ParentAttribute2 VARCHAR(50),
ParentValue VARCHAR(50)
)
INSERT INTO #WhosebugTestParent VALUES ('Oh','Hello','World')
INSERT INTO #WhosebugTestParent VALUES ('World','Goes','Hello')
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestChild
(
ChildId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentId BIGINT,
ChildAttribute1 VARCHAR(50),
ChildAttribute2 VARCHAR(50),
ChildValue VARCHAR(50)
)
INSERT INTO #WhosebugTestChild VALUES (1,'Bobby','Says','Hello')
INSERT INTO #WhosebugTestChild VALUES (1,'Dobby','Starts','Waving')
INSERT INTO #WhosebugTestChild VALUES (2,'Dolly','Says','Hozit')
INSERT INTO #WhosebugTestChild VALUES (2,'Sarah','Says','Hi')
;WITH XMLNAMESPACES ( 'www.example.com' AS ns0)
SELECT P.ParentId AS '@ParentId',
P.ParentAttribute1 AS '@CustomAttribute1',
P.ParentAttribute2 AS 'ParentSub/@CustomAttribute2',
P.ParentValue AS 'WhosebugTestMessage',
/* Building child node with a subquery*/
(SELECT C.ChildId AS '@ChildUniqueId',
C.ChildAttribute1 AS '@ChildAttribute1',
C.ChildAttribute2 AS 'SubChildSingle/@ChildAttribute2',
C.ChildValue AS 'WhosebugTestChild'
FROM #WhosebugTestChild C
WHERE C.ParentId = P.ParentId
FOR XML PATH('CustomChildNode'),TYPE)
FROM #WhosebugTestParent P
FOR XML PATH('WhosebugTestParent'),ROOT('ns0:Root')
结果
<ns0:Root xmlns:ns0="www.example.com">
<WhosebugTestParent ParentId="1"
CustomAttribute1="Oh">
<ParentSub CustomAttribute2="Hello" />
<WhosebugTestMessage>World</WhosebugTestMessage>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="1"
ChildAttribute1="Bobby">
<SubChildSingle ChildAttribute2="Says" />
<WhosebugTestChild>Hello</WhosebugTestChild>
</CustomChildNode>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="2"
ChildAttribute1="Dobby">
<SubChildSingle ChildAttribute2="Starts" />
<WhosebugTestChild>Waving</WhosebugTestChild>
</CustomChildNode>
</WhosebugTestParent>
<WhosebugTestParent ParentId="2"
CustomAttribute1="World">
<ParentSub CustomAttribute2="Goes" />
<WhosebugTestMessage>Hello</WhosebugTestMessage>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="3"
ChildAttribute1="Dolly">
<SubChildSingle ChildAttribute2="Says" />
<WhosebugTestChild>Hozit</WhosebugTestChild>
</CustomChildNode>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="4"
ChildAttribute1="Sarah">
<SubChildSingle ChildAttribute2="Says" />
<WhosebugTestChild>Hi</WhosebugTestChild>
</CustomChildNode>
</WhosebugTestParent>
</ns0:Root>
编辑
这是另一个如何创建具有两个命名空间的基本版本的示例
/* Here is a more basic version */
;WITH XMLNAMESPACES ( 'www.example.com' AS ns0, 'w3/XMLSchema-instance' AS xsi)
SELECT P.ParentAttribute1 AS 'ColumnNames/ParentAttribute1',
P.ParentAttribute2 AS 'ColumnNames/ParentAttribute2',
P.ParentValue AS 'ColumnNames/ParentValue'
FROM #WhosebugTestParent P
FOR XML PATH('CustomTag'),ROOT('ns0:Root')
结果
<ns0:Root xmlns:xsi="w3/XMLSchema-instance" xmlns:ns0="www.example.com">
<CustomTag>
<ColumnNames>
<ParentAttribute1>Oh</ParentAttribute1>
<ParentAttribute2>Hello</ParentAttribute2>
<ParentValue>World</ParentValue>
</ColumnNames>
</CustomTag>
<CustomTag>
<ColumnNames>
<ParentAttribute1>World</ParentAttribute1>
<ParentAttribute2>Goes</ParentAttribute2>
<ParentValue>Hello</ParentValue>
</ColumnNames>
</CustomTag>
</ns0:Root>
已根据原始问题更正 C# 代码,将对象变量 table 转换为 ADO.NET Table。
DataTable dt = new DataTable();
(new OleDbDataAdapter()).Fill(dt, Dts.Variables["User::VariableName"].Value);
提示 - 您应该提供对象本身,而不是像代码片段中那样提供对象到字符串的转换。这就是像
这样的错误的原因
Object is not an ADODB.RecordSet or an ADODB.Record.
我正在尝试使用 SSIS 从 sql table 数据中生成带有自定义标签和属性的 XML 文件。 我编写了从对象变量写入数据的 C# 脚本,但它给我一个错误“对象不是 ADODB.RecordSet 或 ADODB.Record。参数名称:adodb”。 请帮忙。
提前致谢
您可以直接从 MSSQL 输出 xml 而无需使用 SSIS,您可以使用列别名来设置您的自定义 tags/attributes。
请看下面的演示,属性用@前缀别名,标签没有任何前缀,子标签用/
构建使用子查询构建多行子标签
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestParent
(
ParentId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentAttribute1 VARCHAR(50),
ParentAttribute2 VARCHAR(50),
ParentValue VARCHAR(50)
)
INSERT INTO #WhosebugTestParent VALUES ('Oh','Hello','World')
INSERT INTO #WhosebugTestParent VALUES ('World','Goes','Hello')
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestChild
(
ChildId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentId BIGINT,
ChildAttribute1 VARCHAR(50),
ChildAttribute2 VARCHAR(50),
ChildValue VARCHAR(50)
)
INSERT INTO #WhosebugTestChild VALUES (1,'Bobby','Says','Hello')
INSERT INTO #WhosebugTestChild VALUES (1,'Dobby','Starts','Waving')
INSERT INTO #WhosebugTestChild VALUES (2,'Dolly','Says','Hozit')
INSERT INTO #WhosebugTestChild VALUES (2,'Sarah','Says','Hi')
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestParent
(
ParentId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentAttribute1 VARCHAR(50),
ParentAttribute2 VARCHAR(50),
ParentValue VARCHAR(50)
)
INSERT INTO #WhosebugTestParent VALUES ('Oh','Hello','World')
INSERT INTO #WhosebugTestParent VALUES ('World','Goes','Hello')
IF OBJECT_ID('tempdb.dbo.#WhosebugTestParent') IS NOT NULL DROP TABLE #WhosebugTestParent
CREATE TABLE #WhosebugTestChild
(
ChildId BIGINT PRIMARY KEY IDENTITY(1,1),
ParentId BIGINT,
ChildAttribute1 VARCHAR(50),
ChildAttribute2 VARCHAR(50),
ChildValue VARCHAR(50)
)
INSERT INTO #WhosebugTestChild VALUES (1,'Bobby','Says','Hello')
INSERT INTO #WhosebugTestChild VALUES (1,'Dobby','Starts','Waving')
INSERT INTO #WhosebugTestChild VALUES (2,'Dolly','Says','Hozit')
INSERT INTO #WhosebugTestChild VALUES (2,'Sarah','Says','Hi')
;WITH XMLNAMESPACES ( 'www.example.com' AS ns0)
SELECT P.ParentId AS '@ParentId',
P.ParentAttribute1 AS '@CustomAttribute1',
P.ParentAttribute2 AS 'ParentSub/@CustomAttribute2',
P.ParentValue AS 'WhosebugTestMessage',
/* Building child node with a subquery*/
(SELECT C.ChildId AS '@ChildUniqueId',
C.ChildAttribute1 AS '@ChildAttribute1',
C.ChildAttribute2 AS 'SubChildSingle/@ChildAttribute2',
C.ChildValue AS 'WhosebugTestChild'
FROM #WhosebugTestChild C
WHERE C.ParentId = P.ParentId
FOR XML PATH('CustomChildNode'),TYPE)
FROM #WhosebugTestParent P
FOR XML PATH('WhosebugTestParent'),ROOT('ns0:Root')
结果
<ns0:Root xmlns:ns0="www.example.com">
<WhosebugTestParent ParentId="1"
CustomAttribute1="Oh">
<ParentSub CustomAttribute2="Hello" />
<WhosebugTestMessage>World</WhosebugTestMessage>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="1"
ChildAttribute1="Bobby">
<SubChildSingle ChildAttribute2="Says" />
<WhosebugTestChild>Hello</WhosebugTestChild>
</CustomChildNode>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="2"
ChildAttribute1="Dobby">
<SubChildSingle ChildAttribute2="Starts" />
<WhosebugTestChild>Waving</WhosebugTestChild>
</CustomChildNode>
</WhosebugTestParent>
<WhosebugTestParent ParentId="2"
CustomAttribute1="World">
<ParentSub CustomAttribute2="Goes" />
<WhosebugTestMessage>Hello</WhosebugTestMessage>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="3"
ChildAttribute1="Dolly">
<SubChildSingle ChildAttribute2="Says" />
<WhosebugTestChild>Hozit</WhosebugTestChild>
</CustomChildNode>
<CustomChildNode xmlns:ns0="www.example.com"
ChildUniqueId="4"
ChildAttribute1="Sarah">
<SubChildSingle ChildAttribute2="Says" />
<WhosebugTestChild>Hi</WhosebugTestChild>
</CustomChildNode>
</WhosebugTestParent>
</ns0:Root>
编辑
这是另一个如何创建具有两个命名空间的基本版本的示例
/* Here is a more basic version */
;WITH XMLNAMESPACES ( 'www.example.com' AS ns0, 'w3/XMLSchema-instance' AS xsi)
SELECT P.ParentAttribute1 AS 'ColumnNames/ParentAttribute1',
P.ParentAttribute2 AS 'ColumnNames/ParentAttribute2',
P.ParentValue AS 'ColumnNames/ParentValue'
FROM #WhosebugTestParent P
FOR XML PATH('CustomTag'),ROOT('ns0:Root')
结果
<ns0:Root xmlns:xsi="w3/XMLSchema-instance" xmlns:ns0="www.example.com">
<CustomTag>
<ColumnNames>
<ParentAttribute1>Oh</ParentAttribute1>
<ParentAttribute2>Hello</ParentAttribute2>
<ParentValue>World</ParentValue>
</ColumnNames>
</CustomTag>
<CustomTag>
<ColumnNames>
<ParentAttribute1>World</ParentAttribute1>
<ParentAttribute2>Goes</ParentAttribute2>
<ParentValue>Hello</ParentValue>
</ColumnNames>
</CustomTag>
</ns0:Root>
已根据原始问题更正 C# 代码,将对象变量 table 转换为 ADO.NET Table。
DataTable dt = new DataTable();
(new OleDbDataAdapter()).Fill(dt, Dts.Variables["User::VariableName"].Value);
提示 - 您应该提供对象本身,而不是像代码片段中那样提供对象到字符串的转换。这就是像
这样的错误的原因Object is not an ADODB.RecordSet or an ADODB.Record.