【问题标题】:SQL 2008: Extract XML from nvarchar(max)SQL 2008:从 nvarchar(max) 中提取 XML
【发布时间】:2015-09-16 13:20:17
【问题描述】:

我已阅读有关此主题的所有其他帖子,但没有一个对我有用。这个是最近的CONVERTING SQL NVARCHAR(MAX) TO XML

因此,我修改了该代码以尝试适应我的情况。我有一个 nvarchar(max) 列,其中包含作为一个大长字符串的 XML 数据。这不是我的数据库,所以我无法将数据类型更改为 XML。下一个最好的事情是创建一个查询并将其转换为 XML。这是我的代码:

IF OBJECT_ID('tempdb..#XML_Dummy') IS NOT NULL DROP TABLE #XML_Dummy

GO

CREATE TABLE #XML_Dummy
        (
            [ID] [INT] IDENTITY(1, 1)
                                 NOT NULL ,
            [XMLValue] [NVARCHAR](MAX) NULL
        );         
GO
INSERT  INTO #XML_Dummy
                ( 
                    [XMLValue]
                )
select top 10 xmlcol from MyTable

GO  

SELECT
        b.x.value('(/Proponix/Header/SubHeader/InstrumentID)[1]', 'varchar(max)')
FROM
        #XML_Dummy a
        CROSS APPLY (
                                    SELECT
                                     CAST(CAST ([XMLValue] AS VARCHAR(MAX)) AS XML) x
                                ) b;
IF OBJECT_ID('tempdb..#XML_Dummy') IS NOT NULL DROP TABLE #XML_Dummy;   

我不确定我为什么要返回所有 NULLS。我想返回 InstrumentID。这是我的 XML 的摘录:

<?xml version="1.0"?>
<Proponix>
    <Header>
        Header stuff
    </Header>
    <SubHeader>
        <InstrumentID>BS6000000001</InstrumentID>
    </SubHeader>
    A lot more fields

我错过了什么?这是我第一次在 SQL Server 中使用 XML。

【问题讨论】:

    标签: sql-server xml sql-server-2008


    【解决方案1】:

    在您的示例中,SubHeader 不是 Header 的子级。试试:

    b.x.value('(/Proponix/SubHeader/InstrumentID)[1]', 'varchar(max)')
    

    【讨论】:

    • 删除 Header 标签后仍然返回所有 NULLS。
    • 它应该适用于您发布的 xml 摘录。你能发布完整的xml吗?你粘贴的代码和你实际做的有什么不同吗?
    • 完整的 XML 有 283 行长,包含我必须清理的敏感数据。
    • 尝试将问题隔离为可以发布的内容。
    【解决方案2】:

    您尝试将 SubHeader 查找为 Header 的子级,但它是兄弟级...

    试试这个:

    编辑:更改 @x 以模拟具有包含不同 xml_msg 值的 nvarchar 列的表:

    EDIT2:根据聊天中显示的 OP 调用改编

    WITH ConvertedToXML AS 
    ( 
    SELECT xml_msg AsVarchar 
    ,CAST(xml_msg AS XML) AS AsXml 
    FROM myTable 
    ) 
    SELECT ConvertedToXML.AsVarchar 
    ,ConvertedToXML.AsXml 
    ,ConvertedToXML.AsXml.value('(/Proponix/SubHeader/InstrumentID)[1]', 'varchar(max)') AS InstrumentID 
    FROM ConvertedToXML
    

    --旧文本

        declare @x table(xml_msg nvarchar(max));
    insert into @x VALUES
    ('<?xml version="1.0"?>
    <Proponix>
        <Header>
            Header stuff
        </Header>
        <SubHeader>
            <InstrumentID>BS6000000001</InstrumentID>
        </SubHeader>
    </Proponix>')
    ,('<?xml version="1.0"?>
    <Proponix>
        <Header>
            Header stuff
        </Header>
        <SubHeader>
            <InstrumentID>BS6000000002</InstrumentID>
        </SubHeader>
    </Proponix>')
    ,('<?xml version="1.0"?>
    <Proponix>
        <Header>
            Header stuff
        </Header>
        <SubHeader>
            <InstrumentID>BS6000000003</InstrumentID>
        </SubHeader>
    </Proponix>');
    
    WITH ConvertedToXML AS
    (
        SELECT TOP 10 CAST(xml_msg AS XML) AS AsXml FROM @x
    )
    SELECT
            ConvertedToXML.AsXml.value('(/Proponix/SubHeader/InstrumentID)[1]', 'varchar(max)')
    FROM ConvertedToXML
    

    【讨论】:

    • 如果我只是复制并粘贴您的代码,它就可以工作。如果我将其更改为声明 @x nvarchar(max)='select top 10 xml_msg from mytable';它没有。知道为什么吗?
    • 您不能将变量设置为结果集。尝试将 CTE 更改为 SELECT TOP 10 CAST(xml_msg AS XML) AS AsXml FROM mytable(而不是 SELECT cast(@x as xml) AS AsXML)
    • 它仍然返回所有 NULLS。
    • 我刚刚编辑了答案以模拟您的表格。如果有帮助,请投票和/或标记为已接受,谢谢!
    • 再一次,如果我只是复制并粘贴它,这将有效,但如果我使用 select 将其插入到表变量中,它会返回 null。您能否创建一个包含 xml 内容且其中没有 cr/lf 的临时表,并向我展示如何将这些结果插入到表变量中?这与我的环境相匹配。感谢您所有的帮助。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多