Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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
.net 在sql server中加载大xml文件_.net_Sql Server_Vb.net_C# 4.0 - Fatal编程技术网

.net 在sql server中加载大xml文件

.net 在sql server中加载大xml文件,.net,sql-server,vb.net,c#-4.0,.net,Sql Server,Vb.net,C# 4.0,我必须在SQLServer2008R2中加载一个非常大的xml文件。 该文件看起来像: <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?> <listaCupons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <cupomVenda> <codFilial>123456</codFili

我必须在SQLServer2008R2中加载一个非常大的xml文件。 该文件看起来像:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<listaCupons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <cupomVenda>
        <codFilial>123456</codFilial>
        <dtVenda>2013-01-01T00:00:00</dtVenda>
        <numeroDePdv>0.000000000000000</numeroDePdv>
        <cupomFiscal>12345</cupomFiscal>
        <horaVenda xsi:nil="true"/>
        <tipoVenda>1</tipoVenda>
        <vendedorVip>FUlano de tal</vendedorVip>
        <cpfCnpjAdquirente xsi:nil="true"/>
        <item>
            <numeroDoItem>1</numeroDoItem>
            <codigoDoProduto>2134</codigoDoProduto>
            <qtde>1</qtde>
            <valorUnitario>399.000</valorUnitario>
            <ultimoCusto>216.150</ultimoCusto>
        </item>
    </cupomVenda>
</listaCupons>

我接受任何解决方案,因为我必须在.net中使用它。我找到了一些使用sqlbulkcopy类的示例,但我觉得我不能将其用于xmlReader类,我想这是适合本例的

这个问题应该会让你开窍

关键是分解Xml。但是,由于要插入具有标识的表,因此必须使用“自然键”返回“代理标识键”

因此,只要您的“CodDurthit”(我称之为“codFilialNaturalKey”)是一个唯一的约束,您就可以利用它来匹配父表的PK和子表的FK

我为你做了几列数据(这也意味着我没有为你做每一列)。并添加了额外的“item”元素,以显示它适用于多个“item”

还列出了数据集日期时间转换器(UDF)。您需要将您的值提取为varchar,然后通过UDF运行它以转换为DateTime

IF OBJECT_ID('tempdb..#DestinationCupomVendaParentTable') IS NOT NULL
begin
        drop table #DestinationCupomVendaParentTable
end



IF OBJECT_ID('tempdb..#DestinationItemCupomVendaChildTable') IS NOT NULL
begin
        drop table #DestinationItemCupomVendaChildTable
end


CREATE TABLE #DestinationCupomVendaParentTable
(
CupomVendaParentSurrogateIdentityKey int not null identity (1001, 1), 
codFilialNaturalKey int, 
tipoVenda int
)



CREATE TABLE #DestinationItemCupomVendaChildTable
(
DestinationChildSurrogateIdentityKey int not null identity (3001, 1), 
CupomVendaParentSurrogateIdentityKeyFK int, 
numeroDoItemNaturalKey int,
codigoDoProduto int
)





-- Declare XML variable

DECLARE @data XML;

-- Element-centered XML

SET @data = N'
<listaCupons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <cupomVenda>
        <codFilial>123456</codFilial>
        <dtVenda>2013-01-01T00:00:00</dtVenda>
        <numeroDePdv>0.000000000000000</numeroDePdv>
        <cupomFiscal>12345</cupomFiscal>
        <horaVenda xsi:nil="true"/>
        <tipoVenda>1</tipoVenda>
        <vendedorVip>FUlano de tal</vendedorVip>
        <cpfCnpjAdquirente xsi:nil="true"/>
        <item>
            <numeroDoItem>9001</numeroDoItem>
            <codigoDoProduto>2134</codigoDoProduto>
            <qtde>1</qtde>
            <valorUnitario>399.000</valorUnitario>
            <ultimoCusto>216.150</ultimoCusto>
        </item>

        <item>
            <numeroDoItem>9002</numeroDoItem>
            <codigoDoProduto>32134</codigoDoProduto>
            <qtde>1</qtde>
            <valorUnitario>399.000</valorUnitario>
            <ultimoCusto>216.150</ultimoCusto>
        </item>
    </cupomVenda>


    <cupomVenda>
        <codFilial>234567</codFilial>
        <dtVenda>2013-01-01T00:00:00</dtVenda>
        <numeroDePdv>0.000000000000000</numeroDePdv>
        <cupomFiscal>23456</cupomFiscal>
        <horaVenda xsi:nil="true"/>
        <tipoVenda>4</tipoVenda>
        <vendedorVip>FUlano de tal</vendedorVip>
        <cpfCnpjAdquirente xsi:nil="true"/>
        <item>
            <numeroDoItem>9011</numeroDoItem>
            <codigoDoProduto>3256</codigoDoProduto>
            <qtde>4</qtde>
            <valorUnitario>333.44</valorUnitario>
            <ultimoCusto>333.55</ultimoCusto>
        </item>

        <item>
            <numeroDoItem>9013</numeroDoItem>
            <codigoDoProduto>33256</codigoDoProduto>
            <qtde>4</qtde>
            <valorUnitario>333.44</valorUnitario>
            <ultimoCusto>333.55</ultimoCusto>
        </item>
    </cupomVenda>


</listaCupons>

';




INSERT INTO #DestinationCupomVendaParentTable ( codFilialNaturalKey ,  tipoVenda )
SELECT T.parentEntity.value('(codFilial)[1]', 'INT') AS codFilial,
       T.parentEntity.value('(tipoVenda)[1]', 'INT') AS tipoVenda
FROM @data.nodes('listaCupons/cupomVenda') AS T(parentEntity)
/* add a where not exists check on the natural key */
where not exists (
    select null from #DestinationCupomVendaParentTable innerRealTable where innerRealTable.codFilialNaturalKey = T.parentEntity.value('(codFilial)[1]', 'INT') )
;

/* Optional.  You could do a UPDATE here based on matching the #DestinationCupomVendaParentTablecodFilialNaturalKey = T.parentEntity.value('(codFilial)[1]', 'INT')
You could Combine INSERT and UPDATE using the MERGE function on 2008 or later.
 */



INSERT INTO #DestinationItemCupomVendaChildTable (  CupomVendaParentSurrogateIdentityKeyFK ,  numeroDoItemNaturalKey , codigoDoProduto )
SELECT  par.CupomVendaParentSurrogateIdentityKey , 
        T.childEntity.value('(numeroDoItem)[1]', 'INT') AS numeroDoItem,
        T.childEntity.value('(codigoDoProduto)[1]', 'INT') AS codigoDoProduto
FROM @data.nodes('listaCupons/cupomVenda/item') AS T(childEntity)
/* The next join is the "trick".  Join on the natural key (codFilial)....**BUT** insert the CupomVendaParentSurrogateIdentityKey into the table */
join #DestinationCupomVendaParentTable par on par.codFilialNaturalKey = T.childEntity.value('(../codFilial)[1]', 'INT')
where not exists (
    select null from #DestinationItemCupomVendaChildTable innerRealTable where innerRealTable.CupomVendaParentSurrogateIdentityKeyFK = par.CupomVendaParentSurrogateIdentityKey AND  innerRealTable.numeroDoItemNaturalKey = T.childEntity.value('(numeroDoItem)[1]', 'INT'))
;



print '/#DestinationCupomVendaParentTable/'
select * from #DestinationCupomVendaParentTable


print '/#DestinationItemCupomVendaChildTable/'
select * from #DestinationItemCupomVendaChildTable


select codFilialNaturalKey , tipoVenda , numeroDoItemNaturalKey , codigoDoProduto , par.CupomVendaParentSurrogateIdentityKey as ParentPK , child.CupomVendaParentSurrogateIdentityKeyFK as childFK from #DestinationCupomVendaParentTable par join #DestinationItemCupomVendaChildTable child
on par.CupomVendaParentSurrogateIdentityKey = child.CupomVendaParentSurrogateIdentityKeyFK



IF OBJECT_ID('tempdb..#DestinationCupomVendaParentTable') IS NOT NULL
begin
        drop table #DestinationCupomVendaParentTable
end


IF OBJECT_ID('tempdb..#DestinationItemCupomVendaChildTable') IS NOT NULL
begin
        drop table #DestinationItemCupomVendaChildTable
end

你打算用什么样的表结构来存储它?你看过了吗?有一些特定的说明,说明如何将它与.NET.Table cupomVenda、字段idCupomVenda(自动递增)以及xml中的相同字段一起使用,它们的类型顺序分别为:int、int、date、varchar(20)、int、smallint、bit、varchar(80)、char(14)。我还将使用IdItemCupomVenda(自动递增)以及与xml中的字段顺序相同的字段类型存储在Item表中:int,int,int,float,float。加上idCupomVenda(int),使两者之间的关系。谢谢你的帮助@EduardoLion请编辑您的问题以添加此信息;从评论中读取重要的细节非常困难。您是想将xml内容存储在数据库中,还是想将值分解并存储到关系表中的数据库中?非常感谢@granadaCoder!我想这正是我所需要的,我还有一个疑问:如果您有
SET@data=N'
,我该如何使用xml文件的路径?因为它们的大小非常大,我无法打开它们将文本复制到sql server。我从来没有这样做过。我将上述代码放在一个存储过程中,并从DotNet代码调用该存储过程。也就是说,我的“xml”是“内存中的”,而不是磁盘上的文件。所以,您可以将文件推送到sql server中的一个保留表中并从那里读取它,或者文件流读取您的文件并以这种方式向下推。还有一个建议。。一次一行太少,您的整个文件可能太大,您可能想要“分块”…这里有一个演示:“非常大”是相对的。我做过xml…(如果它被写入磁盘上的文件),大约是4MB。你只要试试你的,看看会发生什么。超大意味着1GB甚至更多!那么,如果1000000条记录中有一条不“正确”,那么会发生什么?您是希望999999“运行”,但记录错误的一个,还是希望整个过程失败?如果您想记录偶尔发生的事故,并“继续前进”,那么我将遵循“将其分块”的示例。您将有一种方法来预先验证和/或按摩任何数据,您可以找到正确的“批量大小”(示例中为1000)…并调整该数字。我为我真正的项目所写的逻辑是“一次尝试1000次,如果失败了,那么逐个检查并记录错误的项目”……这样。。
IF OBJECT_ID('tempdb..#DestinationCupomVendaParentTable') IS NOT NULL
begin
        drop table #DestinationCupomVendaParentTable
end



IF OBJECT_ID('tempdb..#DestinationItemCupomVendaChildTable') IS NOT NULL
begin
        drop table #DestinationItemCupomVendaChildTable
end


CREATE TABLE #DestinationCupomVendaParentTable
(
CupomVendaParentSurrogateIdentityKey int not null identity (1001, 1), 
codFilialNaturalKey int, 
tipoVenda int
)



CREATE TABLE #DestinationItemCupomVendaChildTable
(
DestinationChildSurrogateIdentityKey int not null identity (3001, 1), 
CupomVendaParentSurrogateIdentityKeyFK int, 
numeroDoItemNaturalKey int,
codigoDoProduto int
)





-- Declare XML variable

DECLARE @data XML;

-- Element-centered XML

SET @data = N'
<listaCupons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <cupomVenda>
        <codFilial>123456</codFilial>
        <dtVenda>2013-01-01T00:00:00</dtVenda>
        <numeroDePdv>0.000000000000000</numeroDePdv>
        <cupomFiscal>12345</cupomFiscal>
        <horaVenda xsi:nil="true"/>
        <tipoVenda>1</tipoVenda>
        <vendedorVip>FUlano de tal</vendedorVip>
        <cpfCnpjAdquirente xsi:nil="true"/>
        <item>
            <numeroDoItem>9001</numeroDoItem>
            <codigoDoProduto>2134</codigoDoProduto>
            <qtde>1</qtde>
            <valorUnitario>399.000</valorUnitario>
            <ultimoCusto>216.150</ultimoCusto>
        </item>

        <item>
            <numeroDoItem>9002</numeroDoItem>
            <codigoDoProduto>32134</codigoDoProduto>
            <qtde>1</qtde>
            <valorUnitario>399.000</valorUnitario>
            <ultimoCusto>216.150</ultimoCusto>
        </item>
    </cupomVenda>


    <cupomVenda>
        <codFilial>234567</codFilial>
        <dtVenda>2013-01-01T00:00:00</dtVenda>
        <numeroDePdv>0.000000000000000</numeroDePdv>
        <cupomFiscal>23456</cupomFiscal>
        <horaVenda xsi:nil="true"/>
        <tipoVenda>4</tipoVenda>
        <vendedorVip>FUlano de tal</vendedorVip>
        <cpfCnpjAdquirente xsi:nil="true"/>
        <item>
            <numeroDoItem>9011</numeroDoItem>
            <codigoDoProduto>3256</codigoDoProduto>
            <qtde>4</qtde>
            <valorUnitario>333.44</valorUnitario>
            <ultimoCusto>333.55</ultimoCusto>
        </item>

        <item>
            <numeroDoItem>9013</numeroDoItem>
            <codigoDoProduto>33256</codigoDoProduto>
            <qtde>4</qtde>
            <valorUnitario>333.44</valorUnitario>
            <ultimoCusto>333.55</ultimoCusto>
        </item>
    </cupomVenda>


</listaCupons>

';




INSERT INTO #DestinationCupomVendaParentTable ( codFilialNaturalKey ,  tipoVenda )
SELECT T.parentEntity.value('(codFilial)[1]', 'INT') AS codFilial,
       T.parentEntity.value('(tipoVenda)[1]', 'INT') AS tipoVenda
FROM @data.nodes('listaCupons/cupomVenda') AS T(parentEntity)
/* add a where not exists check on the natural key */
where not exists (
    select null from #DestinationCupomVendaParentTable innerRealTable where innerRealTable.codFilialNaturalKey = T.parentEntity.value('(codFilial)[1]', 'INT') )
;

/* Optional.  You could do a UPDATE here based on matching the #DestinationCupomVendaParentTablecodFilialNaturalKey = T.parentEntity.value('(codFilial)[1]', 'INT')
You could Combine INSERT and UPDATE using the MERGE function on 2008 or later.
 */



INSERT INTO #DestinationItemCupomVendaChildTable (  CupomVendaParentSurrogateIdentityKeyFK ,  numeroDoItemNaturalKey , codigoDoProduto )
SELECT  par.CupomVendaParentSurrogateIdentityKey , 
        T.childEntity.value('(numeroDoItem)[1]', 'INT') AS numeroDoItem,
        T.childEntity.value('(codigoDoProduto)[1]', 'INT') AS codigoDoProduto
FROM @data.nodes('listaCupons/cupomVenda/item') AS T(childEntity)
/* The next join is the "trick".  Join on the natural key (codFilial)....**BUT** insert the CupomVendaParentSurrogateIdentityKey into the table */
join #DestinationCupomVendaParentTable par on par.codFilialNaturalKey = T.childEntity.value('(../codFilial)[1]', 'INT')
where not exists (
    select null from #DestinationItemCupomVendaChildTable innerRealTable where innerRealTable.CupomVendaParentSurrogateIdentityKeyFK = par.CupomVendaParentSurrogateIdentityKey AND  innerRealTable.numeroDoItemNaturalKey = T.childEntity.value('(numeroDoItem)[1]', 'INT'))
;



print '/#DestinationCupomVendaParentTable/'
select * from #DestinationCupomVendaParentTable


print '/#DestinationItemCupomVendaChildTable/'
select * from #DestinationItemCupomVendaChildTable


select codFilialNaturalKey , tipoVenda , numeroDoItemNaturalKey , codigoDoProduto , par.CupomVendaParentSurrogateIdentityKey as ParentPK , child.CupomVendaParentSurrogateIdentityKeyFK as childFK from #DestinationCupomVendaParentTable par join #DestinationItemCupomVendaChildTable child
on par.CupomVendaParentSurrogateIdentityKey = child.CupomVendaParentSurrogateIdentityKeyFK



IF OBJECT_ID('tempdb..#DestinationCupomVendaParentTable') IS NOT NULL
begin
        drop table #DestinationCupomVendaParentTable
end


IF OBJECT_ID('tempdb..#DestinationItemCupomVendaChildTable') IS NOT NULL
begin
        drop table #DestinationItemCupomVendaChildTable
end
if exists (select * from sysobjects where id = object_id('udfConvertXmlDateToTsqlDate') and xtype = 'FN')
    drop function udfConvertXmlDateToTsqlDate
GO


CREATE FUNCTION dbo.udfConvertXmlDateToTsqlDate (@input_xml_date varchar(64))

/*


Original Need : When adding a value to a DataSet/datetime column,
                the DataSet stores the date as an xml formatted date
                TSQL does not like xml formatted dates
                This procedure will transfer a xml formatted date,
                into a datetime tsql datatype.
Sample Usage :

        select dbo.udfConvertXmlDateToTsqlDate ('2002-06-20T00:00:00.0000000+05:30') as myConvertedDate
        will yield:
            myConvertedDate                                        
            ------------------------------------------------------ 
            2002-06-20 00:00:00.000


        DateTime.MinValue Test

        select dbo.udfConvertXmlDateToTsqlDate ('0001-01-01T00:00:00-05:00') as myConvertedDate



Notes : 
            The procedure strips out the time part of the datetime.

*/


RETURNS 


datetime

AS
BEGIN


        --This is a DotNet/Xml/DataSet and DateTime.MinValue work around
        if LEFT(@input_xml_date,16)  = '0001-01-01T00:00' --  :00-05:00'
            BEGIN
                return null 
            END



    RETURN 

        --CONVERT(datetime , LEFT(@input_xml_date , (CHARINDEX('T', @input_xml_date))-1))
        CONVERT(datetime , LEFT(CONVERT(nvarchar(4000), @input_xml_date, 126), 10))

        -- SEE "Data Type Coercions" (SQL Server 2000 Books Online)
        -- this has the code above as the translation mechanism
        -- for converted an xml formatted datestamp into a TSQL datetime

END
GO


GRANT REFERENCES ON udfConvertXmlDateToTsqlDate TO public


GO