具有异步结构的openxml

时间:2016-08-02 20:09:54

标签: sql sql-server xml

我正在使用MS SQL Server 2012。

我正在尝试将函数openxml与以下语句/ xml数据一起使用:

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SET @SQL = '<master>
  <List>
    <Col>
      <DisplayFieldName>Peter</DisplayFieldName>
      <Value>
        <string>Yes</string>
      </Value>
    </Col>
    <Col>
      <DisplayFieldName>Tom</DisplayFieldName>
      <Value>
        <string>No</string>
      </Value> 
    </Col>
    <Col>
      <DisplayFieldName>Numerics</DisplayFieldName>     
      <Value>
        <string>50          </string>
        <string>100          </string>
        <string>150          </string>
        <string>200          </string> 
      </Value>
    </Col>
  </List>
</master>'


SELECT @XML = CONVERT(XML,@SQL)

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT *
FROM OPENXML(@hDoc, '/master/List/Col/Value',3)  
WITH 
(
string [varchar](max)
)

EXEC sp_xml_removedocument @hDoc

结果如下:

  string
1 Yes
2 No
3 50

我理解为什么会发生这种情况,但实际上我想显示所有数值(50,100,150,200)或至少显示该字段中的所有值(是,否,50,100,150,200),这也足够了。

3 个答案:

答案 0 :(得分:1)

让xpath更深入。过滤数据。这样的事情。

SELECT text string
FROM OPENXML(@hDoc, '/master/List/Col[DisplayFieldName="Numerics"]/Value/string',3)  
--WITH 
--(
--string [varchar](max)
--)
where text is not null

更新

您还可以使用本机xml方法。

select t.v.value('.','varchar(100)') x
from @xml.nodes('master/List/Col[DisplayFieldName="Numerics"]/Value/string') t(v)

根据我的经验openxml可以更快地处理大文本。

答案 1 :(得分:1)

你可以尝试一下,可能会比你期望的更多:

www.

答案 2 :(得分:1)

FROM OPENXML已过时,不应再使用了(有一些罕见的例外......)

您应该使用.value().nodes().query().exist()等XML方法。

尝试一下:它完全内联(ad-hoc),更易于阅读和维护 - 并且速度更快:

DECLARE @XML AS XML;

SET @XML = '<master>
  <List>
    <Col>
      <DisplayFieldName>Peter</DisplayFieldName>
      <Value>
        <string>Yes</string>
      </Value>
    </Col>
    <Col>
      <DisplayFieldName>Tom</DisplayFieldName>
      <Value>
        <string>No</string>
      </Value> 
    </Col>
    <Col>
      <DisplayFieldName>Numerics</DisplayFieldName>     
      <Value>
        <string>50          </string>
        <string>100          </string>
        <string>150          </string>
        <string>200          </string> 
      </Value>
    </Col>
  </List>
</master>';

SELECT C.value('DisplayFieldName[1]','nvarchar(max)') AS DisplayFieldName
      ,V.value('.','nvarchar(max)') AS string

FROM @XML.nodes('/master/List/Col') AS A(C)
CROSS APPLY C.nodes('Value/string') AS B(V);

结果

DisplayFieldName    string
----------------------------
Peter               Yes
Tom                 No
Numerics            50          
Numerics            100          
Numerics            150          
Numerics            200     

更新

如果您只需要数字,则可以将相同的XQuery过滤器附加到.nodes() XPath,如Alex指出:/master/List/Col[DisplayFieldName="Numerics"]