简体   繁体   English

使用VB.NET 2010从XML文件数据插入和更新SQL表

[英]Insert & Update SQL Table from XML file data using VB.NET 2010

I have been researching and writing/re-writing a program to do this task for a week now. 我一直在研究和编写/重写程序来完成此任务已有一个星期了。 I need some collaboration on this to maybe bring up something I haven't though of before. 我需要对此进行一些合作,以提出我以前从未有过的东西。 Specifically, we have an auto-generated XML file sent to us daily with ~70k records (~75MB in size.) I was asked to make a table on one of the servers (SQL) which contains this information so that it can queried. 具体来说,我们每天都会向我们发送一个自动生成的XML文件,其记录约为70k(大小约为75MB)。我被要求在其中一台服务器(SQL)上制作一张包含此信息的表,以便查询。 Also, this program must Update existing records (if data has changed) and Insert new records DAILY. 另外,该程序必须更新现有记录(如果数据已更改)并每天插入新记录。 Records must not be deleted from the db 记录不能从数据库中删除

Here is the list of methods I have attempted (so far) and reasons they did not work. 这是我尝试过的方法列表(到目前为止)以及它们不起作用的原因。

  1. SQLXMLBulkLoad - This worked excellent for importing the data. SQLXMLBulkLoad-这对于导入数据非常有用。 However, the limitation of the Bulk Load class is that it can not Update and/or Insert. 但是,批量加载类的局限性在于它不能更新和/或插入。 Time for a re-write. 是时候重写了。

  2. SQL OpenRowSet (using SQLCommand, etc.) - This does not work because the server, program, and XML file will all 3 be on different computers. SQL OpenRowSet(使用SQLCommand等)-这不起作用,因为服务器,程序和XML文件将全部3放在不同的计算机上。 These devices CAN be configured to allow each other access to the file (specifically the server), however this method was deemed "Not realistic, too much overhead" Time for a re-write. 可以将这些设备配置为允许彼此访问文件(特别是服务器),但是该方法被认为“不现实,开销太大”。

  3. DataSet Merge, then TableAdapter.Update - This method intitially seemed like it would definitely work. 合并数据集,然后合并TableAdapter.Update-最初似乎确实可以使用此方法。 The idea is simple, use DataSet.XMLRead() method to put the XML data into a table in the dataset, then just add the SQL table to the dataset (Using SQLCommand, etc.), merge the two tables, and then use Table Adapter to Update/Insert the table into the existing SQL table. 这个想法很简单,使用DataSet.XMLRead()方法将XML数据放入数据集中的表中,然后将SQL表添加到数据集中(使用SQLCommand等),合并两个表,然后使用Table将表更新/插入现有SQL表的适配器。 This method seems not to work because the XML file has two nodes (columns) which contains dates. 此方法似乎不起作用,因为XML文件有两个包含日期的节点(列)。 Unfortunately, there is not a uniform Date datatype between SQL and XML. 不幸的是,SQL和XML之间没有统一的Date数据类型。 I even attempted changing all of the date formats from the XML file to the DateTime SQL format, which worked, but still deemed a datatype mismatch exception upon running. 我什至尝试将所有日期格式从XML文件更改为DateTime SQL格式,这种方法虽然有效,但在运行时仍然认为数据类型不匹配异常。

At this point, I am out of ideas. 在这一点上,我没有主意。 This seems to be a task that has surely been done before. 这似乎是肯定已经完成的任务。 I am not necessarily looking for someone to write this code for me (I am fully capable of this), I just need some collaboration on the topic. 我并不一定要找人为我编写此代码(我完全有能力这样做),我只需要在该主题上进行一些协作即可。

Thank You 谢谢

We do something similar with database imports received in XML format, and all I do is pass the XML directly to a stored procedure and then shred the XML using XQuery and OPENXML. 我们对以XML格式接收的数据库导入执行类似的操作,而我所做的只是将XML直接传递到存储过程,然后使用XQuery和OPENXML切碎XML。

Both of those technologies allow you to query XML in SQL as if it was a table in your database. 这两种技术都使您可以查询SQL中的XML,就像它是数据库中的表一样。 Taking that approach, you can just pass your XML to a script or stored procedure, query it in SQL, and insert the results wherever you need them. 采用这种方法,您可以将XML传递给脚本或存储过程,在SQL中对其进行查询,然后在需要的地方插入结果。 Anecdotally, OPENXML is better for processing large XML files , but you could try both and see how they work for you. 有趣的是, OPENXML更适合处理大型XML文件 ,但是您可以尝试两者并看看它们如何为您工作。 Below is an example using OPENXML and a simple merge statement. 以下是使用OPENXML和简单合并语句的示例。

create procedure ImportXml
(
    @importXml xml
)
as
--with OPENXML you have to prepare the document before you use it
--this is unecessary with XQuery
DECLARE @idoc int
EXEC sp_xml_preparedocument @idoc OUTPUT, @importXml;

--this is just a typical Merge statement that will update data if it exists
--and insert it if it does not
merge NormalDataTable
using
(
     --here is where you are querying the XML document directly.  You can 
     --see, it works just like a SQL statement, with a special syntax for
     --specifying where to get data out of the XML document and how to map
     --it to a table structure
     select *
     from openxml(@idoc, '/Root/Element')
     with
     (
         ElementID int '@ElementID',
         ElementValueName varchar(50) '@ElementValueName'
     ) 
) source
on NormalDataTable.ElementID = source.ElementID
when not matched then
    insert ...
when matched then
    update ...

exec sp_xml_removedocument @idoc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM