Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 将大型XML导入SQL Server表的最快方法_Sql Server_Xml_Tsql_Xquery_Openrowset - Fatal编程技术网

Sql server 将大型XML导入SQL Server表的最快方法

Sql server 将大型XML导入SQL Server表的最快方法,sql-server,xml,tsql,xquery,openrowset,Sql Server,Xml,Tsql,Xquery,Openrowset,我有一个非常大而且不漂亮的XML,我想将它导入我的sql server数据库。XML的格式就像我说的非常难看: <myxml xmlns="http://somenamespace.whatever.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"> <mydata> <item>

我有一个非常大而且不漂亮的XML,我想将它导入我的sql server数据库。XML的格式就像我说的非常难看:

<myxml xmlns="http://somenamespace.whatever.com/schemas/xmldata/1/" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
    <mydata>
        <item>
            <record>some</record>
            <record>123</record>
            <record xs:nil="true" />
            <record>random</record>
            <record>234</record>    
        </item>
        <item>
            <record>345</record>
            <record>in all</record>
            <record>these</record>
            <record>cells</record>
            <record>123asdf</record>            
        </item>
        <item>
            <record>how</record>
            <record>to</record>
            <record>import</record>
            <record>987654321</record>
            <record xs:nil="true" />
        </item>
    </mydata>
</myxml>
我可以使用以下代码完成此操作:

CREATE TABLE XmlTable
(
    XMLData XML
)

INSERT INTO XmlTable(XMLData)
SELECT CONVERT(XML, BulkColumn) 
FROM OPENROWSET(BULK 'D:\myverylarge.xml', SINGLE_CLOB) AS x;

DECLARE @XML AS XML
SELECT @XML=XMLData FROM XmlTable

;WITH XMLNAMESPACES ('http://www.w3.org/2001/XMLSchema-instance' as xs, DEFAULT 'http://somenamespace.whatever.com/schemas/xmldata/1/')
INSERT INTO DataFromXml(Column1, Column2, Column3, Column4, Column5)
SELECT  ref.value('record[1][not(@xs:nil = "true")]' ,'varchar(100)') as Column1
        ,ref.value('record[2][not(@xs:nil = "true")]' ,'varchar(100)') as Column2
        ,ref.value('record[3][not(@xs:nil = "true")]' ,'varchar(100)') as Column3
        ,ref.value('record[4][not(@xs:nil = "true")]' ,'varchar(100)') as Column4
        ,ref.value('record[5][not(@xs:nil = "true")]' ,'varchar(100)') as Column5
        FROM @XML.nodes('/myxml/mydata/item') xmlData( ref )
这会运行一到两分钟,这可能不会太糟糕。我没有一个好的推荐人。我的感觉是,这可能要快得多,因为使用OPENROWSET将XML(超过100MB)输入数据库只需几秒钟


我可以优化insert吗?如果可以,我该怎么做?

处理空值在XML中很特别

XML中空值的定义不存在。所以

您可以专门查询
text()
节点

.value('(/a/b/text())[1]','nvarchar(100)')
在这里,您可以找到一个可能的答案(有点隐藏):如果专门查询
text()
节点,您可以在不使用NULL检查谓词的情况下执行所有代码

改变这个

ref.value('record[1][not(@xs:nil = "true")]' ,'varchar(100)')
对此

ref.value('(record[1]/text())[1]' ,'varchar(100)')
什么可能会打破这一点:如果
的内容可能是一个空字符串,那么您将得到一个
NULL
,而不是
'
。但它应该快得多。。。希望,这对你来说没问题


关于性能:阅读答案。它很好地涵盖了你的问题。特别是消耗时间的部分(请遵循此答案中的链接)。

处理空值在XML中很特别

XML中空值的定义不存在。所以

您可以专门查询
text()
节点

.value('(/a/b/text())[1]','nvarchar(100)')
在这里,您可以找到一个可能的答案(有点隐藏):如果专门查询
text()
节点,您可以在不使用NULL检查谓词的情况下执行所有代码

改变这个

ref.value('record[1][not(@xs:nil = "true")]' ,'varchar(100)')
对此

ref.value('(record[1]/text())[1]' ,'varchar(100)')
什么可能会打破这一点:如果
的内容可能是一个空字符串,那么您将得到一个
NULL
,而不是
'
。但它应该快得多。。。希望,这对你来说没问题


关于性能:阅读答案。它很好地涵盖了你的问题。特别是消耗时间的部分(按照本答案中的链接)。

只是为了补充@Shnugo-answer

一切功劳都归于他

这就是您的SQL语句。它将使您的性能提高20%左右。请试一试

;WITH XMLNAMESPACES ('http://www.w3.org/2001/XMLSchema-instance' as xs, DEFAULT 'http://somenamespace.whatever.com/schemas/xmldata/1/')
INSERT INTO DataFromXml(Column1, Column2, Column3, Column4, Column5)
SELECT  ref.value('(record[1]/text())[1]' ,'varchar(100)') as Column1
        ,ref.value('(record[2]/text())[1]' ,'varchar(100)') as Column2
        ,ref.value('(record[3]/text())[1]' ,'varchar(100)') as Column3
        ,ref.value('(record[4]/text())[1]' ,'varchar(100)') as Column4
        ,ref.value('(record[5]/text())[1]' ,'varchar(100)') as Column5
FROM @XML.nodes('/myxml/mydata/item') xmlData(ref);

只是为了补充@Shnugo的答案

一切功劳都归于他

这就是您的SQL语句。它将使您的性能提高20%左右。请试一试

;WITH XMLNAMESPACES ('http://www.w3.org/2001/XMLSchema-instance' as xs, DEFAULT 'http://somenamespace.whatever.com/schemas/xmldata/1/')
INSERT INTO DataFromXml(Column1, Column2, Column3, Column4, Column5)
SELECT  ref.value('(record[1]/text())[1]' ,'varchar(100)') as Column1
        ,ref.value('(record[2]/text())[1]' ,'varchar(100)') as Column2
        ,ref.value('(record[3]/text())[1]' ,'varchar(100)') as Column3
        ,ref.value('(record[4]/text())[1]' ,'varchar(100)') as Column4
        ,ref.value('(record[5]/text())[1]' ,'varchar(100)') as Column5
FROM @XML.nodes('/myxml/mydata/item') xmlData(ref);

“因为使用OPENROWSET将XML(超过100MB)输入数据库只需几秒钟。”-确定吗?或者“在不进行任何解析的情况下读取文件”需要几秒钟的时间。您在那里进行了大量的处理,而OPENROWSET没有这样做。一点也不喜欢。我从来没有比较过,但你也可以试试OpenXml()。“因为使用OPENROWSET将XML(超过100MB)输入数据库只需要几秒钟。”-确定吗?或者“在不进行任何解析的情况下读取文件”需要几秒钟的时间。您在那里进行了大量的处理,而OPENROWSET没有这样做。一点也不喜欢。我从来没有比较过,但你也可以试试OpenXml()。Thx,Yitzhak,我的功劳归于你,+1来自我这边:-)谢谢@Shnugo和Yitzhak。我一定会试试的。那么插入到如何,我们能用更有效的语句替换它吗?@Stackberg,
INSERT
语句没有问题。Thx,Yitzhak,我的功劳归你,+1来自我这边:-)谢谢@Shnugo和Yitzhak。我一定会试试的。那么INSERT INTO呢?我们能用更有效的语句来代替它吗?@Stackberg,
INSERT
语句没有问题。