改进用于xpath计算的SQL查询 数据库
我有一个用于保存XML文档的数据库。 数据库如下所示: 因此,我可以将任何XML文件保存到我的通用数据库中 XPath查询 然后我将XPATH查询转换为SQL查询,用于选择元素改进用于xpath计算的SQL查询 数据库,sql,sql-server,xml,xpath,sql-optimization,Sql,Sql Server,Xml,Xpath,Sql Optimization,我有一个用于保存XML文档的数据库。 数据库如下所示: 因此,我可以将任何XML文件保存到我的通用数据库中 XPath查询 然后我将XPATH查询转换为SQL查询,用于选择元素 已翻译xpath查询的示例: 1) //空[/周期] SELECT e2.docId , e2.startPos , e2.endPos , p2.NodeName , p2.levelEl , p2.pathID From Path p2 , Element e2 , Path p3 , E
- 已翻译xpath查询的示例:
SELECT e2.docId
, e2.startPos
, e2.endPos
, p2.NodeName
, p2.levelEl
, p2.pathID
From Path p2
, Element e2
, Path p3
, Element e3
WHERE e2.docID = p2.docID
AND e2.pathID = p2.pathID
AND p2.NodeName = 'EMPTY'
AND p2.levelEl >= 1
AND e3.docID = p3.docID
AND e3.pathID = p3.pathID
AND p3.NodeName = '_PERIOD_'
AND e2.startPos < e3.startPos
AND e2.endPos > e3.endPos
AND e2.docId = e3.docId
AND p2.levelEl = p3.levelEl - 1
AND e2.docId
= 3147524262 GROUP BY e2.docId
, e2.startPos
, e2.endPos
, p2.NodeName
, p2.levelEl
, p2.pathID
ORDER BY startPos;
从这棵树中我生成了SQL,在这个主题上有很多不同的方法,您的方法将不可避免地导致大量缓慢的自连接。这非常接近解决方案。我建议您使用一些本机XQuery数据库,例如or,它们本身经过优化以处理XQuery,而无需将其重写到SQL中
然而,若您真的想将XQuery重写为SQL,那个么请阅读Torsten Grust提出的示例。他工作背后的理念在实践中得到了体现。他使用的标签方案与您略有不同,但我想这些想法也可以在您的方法中实现。在这个主题上有很多不同之处,您的方法将不可避免地导致大量缓慢的自连接。这非常接近解决方案。我建议您使用一些本机XQuery数据库,例如or,它们本身经过优化以处理XQuery,而无需将其重写到SQL中
然而,若您真的想将XQuery重写为SQL,那个么请阅读Torsten Grust提出的示例。他工作背后的理念在实践中得到了体现。他使用的标签方案与您略有不同,但我想这些想法也可以在您的方法中实现。我必须将Xpath转换为SQL查询,因为这是我的文凭项目。我必须将Xpath转换为SQL查询,因为这是我的文凭项目。您知道吗,SQL Server不会将XML存储为您看到的字符串,而是存储为层次结构树?原生的
XQuery
实现工作得非常好,因为它没有解析字符串。现实世界中的XML可以是任何结构。。。任何XML的通用方法都必须极其复杂(=缓慢)。。。你真的想重新发明一个XQuery
-引擎吗?为什么?啊,看看对Radim答案的评论。。。一个文凭项目。。。您希望如何介绍向后导航(/../
),如何处理xquery函数
,以及FLWOR查询?如果您需要进一步的帮助,请尝试创建一个独立的示例(表DDL、insert、查询、预期输出)。。。但我怀疑,是否有令人信服的方法……我不必涵盖所有类型的查询。我需要例如(//[]和=),仅此而已。不需要进一步改进。我将添加一些工作示例。您是否知道,SQL Server不会将XML存储为您看到的字符串,而是存储为层次结构树?原生的XQuery
实现工作得非常好,因为它没有解析字符串。现实世界中的XML可以是任何结构。。。任何XML的通用方法都必须极其复杂(=缓慢)。。。你真的想重新发明一个XQuery
-引擎吗?为什么?啊,看看对Radim答案的评论。。。一个文凭项目。。。您希望如何介绍向后导航(/../
),如何处理xquery函数
,以及FLWOR查询?如果您需要进一步的帮助,请尝试创建一个独立的示例(表DDL、insert、查询、预期输出)。。。但我怀疑,是否有令人信服的方法……我不必涵盖所有类型的查询。我需要例如(//[]和=),仅此而已。不需要进一步改进。我将添加一些工作示例。
SELECT e5.docId
, e5.startPos
, e5.endPos
, p5.NodeName
, p5.levelEl
, p5.pathID
From Path p2
, Element e2
, Path p3
, Element e3
, Path p4
, Element e4
, Path p5
, Element e5
WHERE e2.docID = p2.docID
AND e2.pathID = p2.pathID
AND p2.NodeName = 'EMPTY'
AND p2.levelEl >= 1
AND e3.docID = p3.docID
AND e3.pathID = p3.pathID
AND p3.NodeName = '_PERIOD_'
AND e2.startPos < e3.startPos
AND e2.endPos > e3.endPos
AND e2.docId = e3.docId
AND p2.levelEl = p3.levelEl - 1
AND e4.docID = p4.docID
AND e4.pathID = p4.pathID
AND p4.NodeName = 'S'
AND e2.startPos < e4.startPos
AND e2.endPos > e4.endPos
AND e2.docId = e4.docId
AND p2.levelEl = p4.levelEl - 1
AND e5.docID = p5.docID
AND e5.pathID = p5.pathID
AND p5.NodeName = 'NP'
AND e4.startPos < e5.startPos
AND e4.endPos > e5.endPos
AND e4.docId = e5.docId
AND p4.levelEl = p5.levelEl - 1
AND e5.docId
= 3147524262 GROUP BY e5.docId
, e5.startPos
, e5.endPos
, p5.NodeName
, p5.levelEl
, p5.pathID
ORDER BY startPos;
ROOT-ROOT (type: ROOT) False
//-EMPTY (type: NODE) False
/-_PERIOD_ (type: NODE) False
/-S (type: NODE) False
/-NP (type: NODE) True