Sql 返回NULL的OpenXML
我正在尝试使用Microsoft SQL Server中的OpenXML通过以下查询将xml导入我的数据库:Sql 返回NULL的OpenXML,sql,sql-server,xml,Sql,Sql Server,Xml,我正在尝试使用Microsoft SQL Server中的OpenXML通过以下查询将xml导入我的数据库: DECLARE @xml XML; DECLARE @y INT; SET @xml = '<ArrayOfArticle xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Article>
DECLARE @xml XML;
DECLARE @y INT;
SET @xml
= '<ArrayOfArticle xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Article>
<ScriptId xmlns="https://test.com/">5135399</ScriptId>
<Title xmlns="https://test.com/">Stocks divided into two corners</Title>
<Mediatype xmlns="https://test.com/">News papeer</Mediatype>
<Abstract xmlns="https://test.com/">Foreign capital doubled this year.</Abstract>
<ScriptDate xmlns="https://test.com/">2017-12-30T00:00:00</ScriptDate>
<ScriptTypeId xmlns="https://test.com/">1</ScriptTypeId>
<ScriptType xmlns="https://test.com/">News general</ScriptType>
<Media xmlns="https://test.com/">Times</Media>
<ArticleUrl xmlns="https://test.com/">http://test.com</ArticleUrl>
<AnalysisResult xmlns="https://test.com/">
<Analysis>
<Regno>111</Regno>
<Name>New York Times</Name>
<Result>1</Result>
<ResultName>Positive</ResultName>
</Analysis>
<Analysis>
<Regno>222</Regno>
<Name>Washington Post</Name>
<Result>1</Result>
<ResultName>Negative</ResultName>
</Analysis>
</AnalysisResult>
<FacebookStats xmlns="https://test.com/">
<ShareCount xsi:nil="true" />
<LikeCount xsi:nil="true" />
<CommentCount xsi:nil="true" />
<TotalCount xsi:nil="true" />
</FacebookStats>
<MediaScore xmlns="https://test.com/">
<MediaScore>
<Regno>111</Regno>
<CompanyName>New York Times</CompanyName>
<MediaScoreID>2</MediaScoreID>
<Name>Neither</Name>
</MediaScore>
<MediaScore>
<Regno>222</Regno>
<CompanyName>Washington Post</CompanyName>
<MediaScoreID>2</MediaScoreID>
<Name>Neither</Name>
</MediaScore>
</MediaScore>
<Page xmlns="https://test.com/">26</Page>
<ProgramId xmlns="https://test.com/">0</ProgramId>
<ProgramTime xmlns="https://test.com/" xsi:nil="true" />
<ProgramLength xmlns="https://test.com/">0</ProgramLength>
<ProgramOrder xmlns="https://test.com/">0</ProgramOrder>
</Article>
</ArrayOfArticle>';
EXEC sp_xml_preparedocument @y OUTPUT, @xml;
SELECT *
FROM
OPENXML(@y, '/ArrayOfArticle/Article', 1)
WITH
(
ScriptId VARCHAR(20),
Title VARCHAR(30),
Mediatype VARCHAR(30)
);
DECLARE@xml;
声明@y INT;
SET@xml
='不要使用OPENXML中的。这种方法(连同准备和删除文件的相应SPs)已经过时,不应再使用
尝试XML类型的本机方法,在本例中为.value()
:
关于名称空间,您的XML相当奇怪。如果它的创建在您的控制之下,您应该尝试清理这个名称空间混乱。不寻常的是,您的XML反复声明default名称空间
您可以将深度搜索与/
以及命名空间通配符*:
--GetItEasyCheesy (not recommended)
SELECT @xml.value(N'(//*:ScriptId)[1]',N'int') AS ScriptId
,@xml.value(N'(//*:Title)[1]',N'nvarchar(max)') AS Title
,@xml.value(N'(//*:Mediatype )[1]',N'nvarchar(max)') AS Mediatype ;
可以将名称空间声明为默认名称空间,但在这种情况下,必须通配符外部元素,因为它们不属于此名称空间:
--Use a default namespace
WITH XMLNAMESPACES(DEFAULT 'https://test.com/')
SELECT @xml.value(N'(/*:ArrayOfArticle/*:Article/ScriptId/text())[1]',N'int') AS ScriptId
,@xml.value(N'(/*:ArrayOfArticle/*:Article/Title/text())[1]',N'nvarchar(max)') AS Title
,@xml.value(N'(/*:ArrayOfArticle/*:Article/Mediatype/text())[1]',N'nvarchar(max)') AS Mediatype;
建议的方法是将内部名称空间绑定到前缀并使用
--Recommended
WITH XMLNAMESPACES('https://test.com/' AS ns)
SELECT @xml.value(N'(/ArrayOfArticle/Article/ns:ScriptId/text())[1]',N'int') AS ScriptId
,@xml.value(N'(/ArrayOfArticle/Article/ns:Title/text())[1]',N'nvarchar(max)') AS Title
,@xml.value(N'(/ArrayOfArticle/Article/ns:Mediatype/text())[1]',N'nvarchar(max)') AS Mediatype;
如果您的
包含多个
,则可以使用.nodes()
将所有节点作为派生表获取。在本例中,查询是
WITH XMLNAMESPACES('https://test.com/' AS ns)
SELECT art.value(N'(ns:ScriptId/text())[1]',N'int') AS Recommended
,art.value(N'(ns:Title/text())[1]',N'nvarchar(max)') AS Title
,art.value(N'(ns:Mediatype/text())[1]',N'nvarchar(max)') AS Mediatype
FROM @xml.nodes(N'/ArrayOfArticle/Article') AS A(art);
如果XML包含名称空间,我将使用xquery从XML中提取数据
使用附加元素更新
DECLARE @xml XML;
SET @xml
= '<ArrayOfArticle xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Article>
<ScriptId xmlns="https://test.com/">5135399</ScriptId>
<Title xmlns="https://test.com/">Stocks divided into two corners</Title>
<Mediatype xmlns="https://test.com/">News papeer</Mediatype>
<Abstract xmlns="https://test.com/">Foreign capital doubled this year.</Abstract>
<ScriptDate xmlns="https://test.com/">2017-12-30T00:00:00</ScriptDate>
<ScriptTypeId xmlns="https://test.com/">1</ScriptTypeId>
<ScriptType xmlns="https://test.com/">News general</ScriptType>
<Media xmlns="https://test.com/">Times</Media>
<ArticleUrl xmlns="https://test.com/">http://test.com</ArticleUrl>
<AnalysisResult xmlns="https://test.com/">
<Analysis>
<Regno>111</Regno>
<Name>New York Times</Name>
<Result>1</Result>
<ResultName>Positive</ResultName>
</Analysis>
<Analysis>
<Regno>222</Regno>
<Name>Washington Post</Name>
<Result>1</Result>
<ResultName>Negative</ResultName>
</Analysis>
</AnalysisResult>
<FacebookStats xmlns="https://test.com/">
<ShareCount xsi:nil="true" />
<LikeCount xsi:nil="true" />
<CommentCount xsi:nil="true" />
<TotalCount xsi:nil="true" />
</FacebookStats>
<MediaScore xmlns="https://test.com/">
<MediaScore>
<Regno>111</Regno>
<CompanyName>New York Times</CompanyName>
<MediaScoreID>2</MediaScoreID>
<Name>Neither</Name>
</MediaScore>
<MediaScore>
<Regno>222</Regno>
<CompanyName>Washington Post</CompanyName>
<MediaScoreID>2</MediaScoreID>
<Name>Neither</Name>
</MediaScore>
</MediaScore>
<Page xmlns="https://test.com/">26</Page>
<ProgramId xmlns="https://test.com/">0</ProgramId>
<ProgramTime xmlns="https://test.com/" xsi:nil="true" />
<ProgramLength xmlns="https://test.com/">0</ProgramLength>
<ProgramOrder xmlns="https://test.com/">0</ProgramOrder>
</Article>
</ArrayOfArticle>'
DECLARE @T TABLE (XmlCol XML)
INSERT INTO @T
SELECT @xml
;WITH XMLNAMESPACES ('https://test.com/' as p1)
SELECT z.t.value ('../../p1:ScriptId[1]',' varchar(100)') ScriptId,
z.t.value ('../../p1:Title[1]',' varchar(100)') Title,
z.t.value ('../../p1:Mediatype[1]',' varchar(100)') Mediatype,
z.t.value ('p1:CompanyName[1]', 'varchar(100)') CompanyName
FROM @T t
CROSS APPLY XmlCol.nodes ('/ArrayOfArticle/Article/p1:MediaScore/p1:MediaScore') z(t)
DECLARE@xml;
SET@xml
= '
5135399
股票分成两个角
新闻记者
今年外资翻了一番。
2017-12-30T00:00:00
1.
新闻局长
时代
http://test.com
111
纽约时报
1.
肯定的
222
华盛顿邮报
1.
消极的
111
纽约时报
2.
也不
222
华盛顿邮报
2.
也不
26
0
0
0
'
声明@T表(xmlcolxml)
插入@T
选择@xml
;使用XMLNAMESPACES('https://test.com/“作为p1)
选择z.t.value(“../../p1:ScriptId[1]”、“varchar(100)”ScriptId,
z、 t.value(“../../p1:Title[1]”,“'varchar(100)”Title,
z、 t.value(“../../p1:Mediatype[1]”,“'varchar(100)”Mediatype,
z、 t.value('p1:CompanyName[1]”,'varchar(100)'CompanyName
来自@T
交叉应用XmlCol.nodes('/ArrayOfArticle/Article/p1:MediaScore/p1:MediaScore')z(t)
声明@y INT
EXEC sp_xml_preparedocument@y OUTPUT,@xml,
''
挑选*
从…起
OPENXML(@y,'/ArrayOfArticle/Article',2)
具有
(
[ScriptId]VARCHAR(20)“x:ScriptId',--谢谢,我理解。回答很好,我的工具中有+1。我怎样才能得到嵌套值?例如MediaScore中的CompanyName?@theOGloc,我已经用嵌套MediaScoreWorks中的CompanyName摘录更新了脚本。我怎样才能得到嵌套值?例如MediaScore内的公司名称示例?@theOGloc:请提出一个新问题。这个答案完全解决了您原来的问题。谢谢。
DECLARE @y INT
EXEC sp_xml_preparedocument @y OUTPUT, @xml,
'<ns xmlns:x="https://test.com/"/>'
SELECT *
FROM
OPENXML(@y, '/ArrayOfArticle/Article', 2)
WITH
(
[ScriptId] VARCHAR(20) 'x:ScriptId', --<< and so on
[Title] VARCHAR(30),
Mediatype VARCHAR(30)
)
EXEC sp_xml_removedocument @y --<< lost in your code