Sql 返回NULL的OpenXML

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>

我正在尝试使用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)
    );
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