查询到sql server 2008,我有一个表,其中一列存储xmldata作为文本,让我们说:
TABLE(identifier varchar(15), xmldata text)
xml看起来有点像这样(注意,没有明确的根元素)
<notRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns = "tons.o/NDA/HIPAA/" attribute_1 = "value_1" ... attribute_n = "value_n" >
<node nAttribute1 = "41pha0000" nAttribute2 = "VALUE" />
</notRoot>
-exactly 1 notRoot,并且每行正好存储1个节点
-trying访问节点属性值
- 这将永远运行,并将极大地伤害它
- (xml将成为其他地方的文本,我需要知道将来如何做到这一点)
所以,为了获取它并让该节点可以作为xml访问(理想情况下,否则我将不得不使用linq或者使其成为可移植的),我将其转换为xml,并尝试使用不同的XQuery关于演员价值的方法。我已经将我观察到的各种行为包含在我的失败中:
select top 1
(CAST(l.xmldata as xml)).query('.') --returns the whole shebang
,(CAST(l.xmldata as xml)).exist('.') --returns 1
,(CAST(l.xmldata as xml)).exist('(.)[0]') -- 0, as mentioned below, XML isn't 0 indexed
,(CAST(l.xmldata as xml)).exist('(.)[1]') -- 1, so this exists
,(CAST(l.xmldata as xml)).exist('/notRoot') -- 0
,(CAST(l.xmldata as xml)).exist('//notRoot') -- 0 (sorry ZLK, it was a good idea)
,(CAST(l.xmldata as xml)).exist('/notRoot/node') -- 0
,(CAST(l.xmldata as xml)).exist('(/notRoot)[0]') -- 0, as expected
,(CAST(l.xmldata as xml)).exist('(/notRoot)[1]') -- 0, unfortunate
,(CAST(l.xmldata as xml)).exist('(//notRoot)[1]')-- 0, ditto
from database.dbo.log l
是否没有根元素? 它是否必须存储在xml类型的变量中才能使用此XQuery(以不同方法的MSDN参考为模型)? 任何人都可以向我解释这种行为吗?
答案 0 :(得分:0)
作为开始:
TEXT
已被弃用超过15年。未来的版本将不再支持它XML
类型的列中。真的,如果你能改变这一点,那就去做吧!<node n_attributes = "n_values" ...>
这样的东西对你来说可能很清楚,但对于外部则不然。请阅读我的评论中的问题并提供更多详细信息!我刚问了我的魔法水晶球,它告诉我,你可能正在寻找这样的东西:
<强>假设强>
<notRoot>
个元素<root>
元素<node>
<notRoot>
试试这个:
- 一个声明的虚拟表到模拟你的场景
DECLARE @dummy TABLE(identifier varchar(15), xmldata text);
INSERT INTO @dummy VALUES
('record 1','<notRoot nr_a1 = "nr1_v1" nr_a2="nr1_v2">
<node n1= "v1" n2="v2" n3="v3"/>
</notRoot>
<notRoot nr_a1 = "nr2_v1" nr_a2="nr2_v2">
<node n1= "a" n2="b" n3="c"/>
</notRoot>')
,('record 2','<notRoot nr_a1 = "one more" nr_a2="xyz">
<node n1= "1" n2="2" n3="3"/>
</notRoot>
<notRoot nr_a1 = "and even more" nr_a2="more more more">
<node n1= "100" n2="200" n3="300"/>
</notRoot>');
WITH Casted AS
(
SELECT t.identifier
,CAST(t.xmldata AS XML) AS TheXml
FROM @dummy AS t
)
- 查询
SELECT c.identifier
,c.TheXml
,nr.value(N'@nr_a1',N'nvarchar(max)') AS notRoot_a1
,nr.value(N'@nr_a2',N'nvarchar(max)') AS notRoot_a2
,nr.value(N'(node/@n1)[1]',N'nvarchar(max)') AS node_n1
,nr.value(N'(node/@n2)[1]',N'nvarchar(max)') AS node_n2
,nr.value(N'(node/@n3)[1]',N'nvarchar(max)') AS node_n3
FROM Casted AS c
OUTER APPLY c.TheXml.nodes(N'//notRoot') AS A(nr)
结果:
identifier notRoot_a1 notRoot_a2 node_n1 node_n2 node_n3
record 1 nr1_v1 nr1_v2 v1 v2 v3
record 1 nr2_v1 nr2_v2 a b c
record 2 one more xyz 1 2 3
record 2 and even more more more more 100 200 300
根据您的编辑,有一个默认命名空间,必须声明或通配(*:elementname
)。
您的编辑看起来更像是您事先不知道属性的数量,也不知道它们的名称。由于<notRoot>
中的<node>
和 n属性中可能有n个属性,因此您将获得每个结果。可能会更好地拨打两个不同的电话。
如果您事先知道属性的名称(即使并非所有属性都被所有XML使用,也会更容易......
试试这个:
DECLARE @dummy TABLE(identifier varchar(15), xmldata text);
INSERT INTO @dummy VALUES
('record 1','<notRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns = "tons.o/NDA/HIPAA/"
attribute_1 = "value_1" attribute_n = "value_n" >
<node nAttribute1 = "41pha0000" nAttribute2 = "VALUE" />
</notRoot>
<notRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns = "tons.o/NDA/HIPAA/"
attribute_1 = "other" attribute_n = "other_n" >
<node nAttribute1 = "xyz" nAttribute2 = "blah" />
</notRoot>');
WITH XMLNAMESPACES(DEFAULT 'tons.o/NDA/HIPAA/')
,Casted AS
(
SELECT t.identifier
,CAST(t.xmldata AS XML) AS TheXml
FROM @dummy AS t
)
--the query
SELECT Casted.identifier
,nrAttr.value(N'local-name(.)',N'nvarchar(max)') AS notRoot_attr_name
,nrAttr.value(N'.',N'nvarchar(max)') AS notRoot_attr
,ndAttr.value(N'local-name(.)',N'nvarchar(max)') AS notRoot_attr_name
,ndAttr.value(N'.',N'nvarchar(max)') AS notRoot_attr
FROM Casted
OUTER APPLY Casted.TheXml.nodes(N'/notRoot/@*') AS A(nr)
OUTER APPLY nr.nodes(N'@*') AS B(nrAttr)
OUTER APPLY nr.nodes(N'node') AS C(nd)
OUTER APPLY nd.nodes(N'@*') AS D(ndAttr)
结果
record 1 attribute_1 value_1 nAttribute1 41pha0000
record 1 attribute_1 value_1 nAttribute2 VALUE
record 1 attribute_n value_n nAttribute1 41pha0000
record 1 attribute_n value_n nAttribute2 VALUE
record 1 attribute_1 other nAttribute1 xyz
record 1 attribute_1 other nAttribute2 blah
record 1 attribute_n other_n nAttribute1 xyz
record 1 attribute_n other_n nAttribute2 blah