我的架构中有多个关系。例如,一个包有许多任务组,任务组又有许多任务。所有表都通过多个表链接在一起,例如包含主键和taskgroup的主键。 (我知道这不是严格需要的,因为XML是一对多的,但我想不出更好的结构。)
是否可以将查询结果作为XML,反映一对多结构?所以,结果应该是这样的:
<package id=1>
<taskgroup id=1>
<task id=1>
<task id=2>
</taskgroup>
<taskgroup id=2>
<task id=3>
</taskgroup>
</package>
通过使用XMLELEMENT()
和XMLATTRIBUTE()
函数来完成所有任务,我设法获得了我想要的一部分。像这样:
SELECT XMLELEMENT(name task,
XMLATTRIBUTES(p.name as packageName),
XMLELEMENT(name description, t.description),
XMLELEMENT(name tutorial,
XMLELEMENT(name someTaskChild1, t.data1)),
XMLELEMENT(name objectives,
XMLELEMENT(name someTaskChild2, t.data2)),
)
FROM packages p
INNER JOIN package_taskgroup pt ON p.id = pt.package_id
INNER JOIN taskgroups tg on pt.taskgroup_id = tg.id
INNER JOIN taskgroup_task tt on tg.id = tt.taskgroup_id
INNER JOIN tasks t on tt.task_id = t.id
WHERE p.id = somePackageId AND tg.id = someTaskGroupId
问题是如何将这些任务分组到其父表元素中?
答案 0 :(得分:6)
尝试:
SELECT p.id as pack_id,
XMLELEMENT(name taskgroup,
XMLATTRIBUTES(tg.id as id),
XMLAGG(XMLELEMENT(name task,
XMLATTRIBUTES(t.id as id)) as xml_task_group
FROM packages p
JOIN package_taskgroup pt ON p.id = pt.package_id
JOIN taskgroups tg on pt.taskgroup_id = tg.id
JOIN taskgroup_task tt on tg.id = tt.taskgroup_id
JOIN tasks t on tt.task_id = t.id
WHERE p.id = somePackageId
GROUP BY p.id, tg.id
这将为您指定的p.id
提供所有任务组。
然后:
SELECT XMLELEMENT(name package,
XMLATTRIBUTES(pack_id as id),
XMLAGG(xml_task_group))
FROM (previous SELECT here)
这将为您提供您指定的结构。
详细信息:XMLAGG,XML functions
加入的选择将如下所示:
SELECT XMLELEMENT(name package,
XMLATTRIBUTES(pack_id as id),
XMLAGG(xml_task_group))
FROM (SELECT p.id as pack_id,
XMLELEMENT(name taskgroup,
XMLATTRIBUTES(tg.id as id),
XMLAGG(XMLELEMENT(name task,
XMLATTRIBUTES(t.id as id)
))) as xml_task_group
FROM packages p
JOIN package_taskgroup pt ON p.id = pt.package_id
JOIN taskgroups tg on pt.taskgroup_id = tg.id
JOIN taskgroup_task tt on tg.id = tt.taskgroup_id
JOIN tasks t on tt.task_id = t.id
WHERE p.id = somePackageId
GROUP BY p.id, tg.id) t
GROUP BY pack_id
我只是将第一个选择复制到第二个的FROM
子句中。
答案 1 :(得分:0)
您可以尝试这样:
SELECT
T0."Mail",
T0."UserName",
(SELECT xmlagg(xmlelement(name Screens,
XMLELEMENT(name "IN1_ID","IN1."ID"),
XMLELEMENT(name "IN1_Name", IN1."Name")
)
)
FROM "Advertisement"."Screen" IN1
WHERE T0."ID" = IN1."PlatformID"
) AS Screens
FROM "Sales"."Platform" T0
XNL输出将如下:
<screens>
<IN1_PlatformID>14</IN1_PlatformID>
<IN1_Name>My Name</IN1_Name>
</screens>
<screens>
<IN1_PlatformID>15</IN1_PlatformID>
<IN1_Name>My Name 2</IN1_Name>
</screens>
在c#侧,你需要插入一个根节点来阅读它。
var doc = new System.Xml.XmlDocument();
doc.LoadXml("<rows>" + row["Screens"].ToString() + "</rows>");
之后,您可以转换为数据集以轻松读取屏幕数据:
var xmlReader = new System.Xml.XmlNodeReader(doc);
var dataSet = new System.Data.DataSet();
dataSet.ReadXml(xmlReader);
foreach (System.Data.DataRow item in dataSet.Tables[0].Rows){
...
}