从xml获取数据类型-SQL

时间:2019-01-13 11:07:12

标签: sql-server xml-parsing

我想从xml中提取列名称,值和数据类型。

DECLARE @Xml XML = (Select Top 1 T.* From(VALUES('John',26,GETDATE())) As T(Name,Age,DateOfJoin)
                    FOR XML RAW, ELEMENTS);
Select
    ColumnName = T.X.value('local-name(.)', 'varchar(max)'),
    ColumnValue = T.X.value('text()[1]', 'nvarchar(128)'),
    DataType = '?'
From @Xml.nodes('/row/*') as T(X)

输出:

enter image description here

我可以在xml中获取数据类型,但是无法解析。

DECLARE @Xml XML = (Select Top 1 T.* From(VALUES('John',26,GETDATE())) As T(Name,Age,DateOfJoin)
                    FOR XML RAW, ELEMENTS, XMLSCHEMA);
Select @Xml As XML

输出:

enter image description here

XML-漂亮打印:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" targetNamespace="urn:schemas-microsoft-com:sql:SqlRowSet1" elementFormDefault="qualified">
    <xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
    <xsd:element name="row">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="Name">
                    <xsd:simpleType>
                        <xsd:restriction base="sqltypes:varchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreNonSpace IgnoreKanaType IgnoreWidth">
                            <xsd:maxLength value="4" />
                        </xsd:restriction>
                    </xsd:simpleType>
                </xsd:element>
                <xsd:element name="Age" type="sqltypes:int" />
                <xsd:element name="DateOfJoin" type="sqltypes:datetime" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
<row xmlns="urn:schemas-microsoft-com:sql:SqlRowSet1"><Name>John</Name><Age>26</Age><DateOfJoin>2019-01-13T16:28:40.903</DateOfJoin></row>

2 个答案:

答案 0 :(得分:1)

这里还有另一个选择: sys.dm_exec_describe_first_result_set

示例

Declare @tsql nvarchar(max) =  'Select * From(VALUES(''John'',26,getdate())) As T(Name,Age,DateOfJoin)'

DECLARE @Xml XML = (Select * From(VALUES('John',26,getdate())) As T(Name,Age,DateOfJoin) FOR XML RAW, ELEMENTS);


Select ColumnName  = T.X.value('local-name(.)', 'varchar(max)'),
       ColumnValue = T.X.value('text()[1]', 'nvarchar(128)')
      ,DataType    = B.system_type_name
 From  @Xml.nodes('/row/*') as T(X)
 Join  sys.dm_exec_describe_first_result_set(@SQL,null,null)  B
   on  T.X.value('local-name(.)', 'varchar(max)') = B.name

返回

ColumnName  ColumnValue             DataType
Name        John                    varchar(4)
Age         26                      int
DateOfJoin  2019-01-13T09:00:51.337 datetime

答案 1 :(得分:0)

来自@Larnu's答案

DECLARE @Xml XML = (Select Top 1 T.* From(VALUES('John',26,GETDATE())) As T(Name,Age,DateOfJoin)
                    FOR XML RAW, ELEMENTS, XMLSCHEMA);


WITH XMLNAMESPACES ('http://www.w3.org/2001/XMLSchema' AS xsd)
SELECT ColumnName = X.e.value('@name','sysname'),
       ColumnValue = T.X.value('text()[1]', 'nvarchar(max)'),
       DataType = REPLACE(ISNULL(X.e.value('@type','nvarchar(140)'), X.e.value('(./xsd:simpleType/xsd:restriction/@base)[1]','nvarchar(140)')), 'sqltypes:', '')
FROM @XML.nodes('xsd:schema/xsd:element/xsd:complexType/xsd:sequence/xsd:element') X(e)
INNER JOIN @Xml.nodes('/*/*') as T(X) ON T.X.value('local-name(.)', 'nvarchar(128)') = X.e.value('@name','sysname')

输出:

enter image description here