我正在尝试使用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>
<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)
);
但查询只返回NULL值。我在这里错过了什么?使用SSIS导入XML是否最佳?不确定我能在给定的时间内提供多少细节。
答案 0 :(得分:5)
请勿使用FROM OPENXML
。这种方法(连同相应的SP准备和删除文档)已经过时,不应再使用了。
尝试使用XML类型的本机方法,在本例中为.value()
:
您的XML相当奇怪 - 与名称空间有关。如果它的创建在你的控制之下,你应该尝试清理这个命名空间。不同寻常的是,您的XML反复声明默认命名空间。
您可以将深度搜索与//
一起使用,并使用命名空间通配符*:
--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;
如果您的<ArrayOfArticles>
包含多个<Article>
,则可以使用.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);
答案 1 :(得分:2)
您的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)
答案 2 :(得分:1)
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