这个OpenXML有什么问题?

3
ALTER PROCEDURE GetSingersGenere
(@SingerData ntext)
AS
BEGIN
    DECLARE @hDoc int      
    exec sp_xml_preparedocument @hDoc OUTPUT,@SingerData


    IF OBject_id('SingerTable') IS NOT NULL
    BEGIN
        DROP TABLE SingerTable

    END

    CREATE TABLE SingerTable
    (
    SingerName varchar(200)
    )

    INSERT INTO SingerTable 
    (
    SingerName
    )
    SELECT * FROM OpenXML (@hDoc,'/Singers/Singer')
    WITH (SingerName varchar(200)) XMLSinger

    SELECT * FROM SingerTable
END

我现在的执行方式是这样的:

EXEC GetSingersGenere
 '<Singers>
<Singer>
Joe
</Singer>
<Singer>
ACDC
</Singer>
</Singers>'

我看到 NULL 被插入到了表中。有人可以指出错误吗?


1
我对OpenXML不是很了解,但从XPath的角度来看,你尝试过 SELECT * FROM OpenXML (@hDoc,'/Singers/Singer/text()') 吗?你的XPath选择元素...也许除非你明确要求它,否则选择不会将它们转换为它们的文本内容。 - LarsH
你说的是哪个OpenXml?是Microsoft Office使用的格式吗?那我不明白这与你的SQL查询有什么关系。能否请您添加更多细节? - Dirk Vollmar
@0xA3,我在谈论Sql Server中的OpenXML语句。 - Ashish Gupta
2个回答

2

默认情况下,OPENXML将查看属性值或子元素以获取数据。如果您将选择写成:

SELECT * FROM OpenXML (@hDoc,'/Singers/Singer')
    WITH (SingerName varchar(200) 'text()') XMLSinger

应该可以正常工作。请注意,在模式映射中添加了“text()”,以指定我们只想要节点的文本值,而不是任何属性值。


+1,绝对有效。我完全忽略了“text()”部分。谢谢! - Ashish Gupta

2

为什么还要费劲地使用笨重的OpenXML?只需使用SQL Server中基本的XQuery支持即可更加优雅地完成此操作:

ALTER PROCEDURE GetSingersGenre(@SingerData XML)
AS
BEGIN
   INSERT INTO dbo.SingerTable(SingerName)
      SELECT
         Singer.Node.value('(.)[1]', 'varchar(50)')
      FROM
         @SingerData.nodes('/Singers/Singer') AS Singer(Node)

@ydobomai:不确定 - 这很大程度上取决于您的XML,大小,结构和硬件。试试吧!尝试两种方法并测量 - 这是唯一可靠的了解的方法... - marc_s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接