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
如何从XML文件更新SQL数据库表?_Sql_Xml_Database_Sql Update - Fatal编程技术网

如何从XML文件更新SQL数据库表?

如何从XML文件更新SQL数据库表?,sql,xml,database,sql-update,Sql,Xml,Database,Sql Update,我发现了一个每日更新的XML文件(在web上),我想从这个文件中的数据创建一个数据库表,并可以选择更新它,有什么帮助吗 我使用的是Microsoft visual web developer 2010,我该怎么办?我会将它存储在一个表中,如下所示(使用您选择的主键,我猜是货币代码和上次更新的代理标识列或复合键): 然后,您可以使用存储过程保存文件,并使用以下方法查询XML: 虽然如果使用复合键,则需要使用“合并”: CREATE PROCEDURE dbo.SaveCurrencyXMLMERG

我发现了一个每日更新的XML文件(在web上),我想从这个文件中的数据创建一个数据库表,并可以选择更新它,有什么帮助吗


我使用的是Microsoft visual web developer 2010,我该怎么办?

我会将它存储在一个表中,如下所示(使用您选择的主键,我猜是货币代码和上次更新的代理标识列或复合键):

然后,您可以使用存储过程保存文件,并使用以下方法查询XML:

虽然如果使用复合键,则需要使用“合并”:

CREATE PROCEDURE dbo.SaveCurrencyXMLMERGE @XML XML
AS
    WITH C AS
    (   SELECT  LastUpdate = @XML.value('CURRENCIES[1]/LAST_UPDATE[1]', 'DATE'),
                CurrencyCode = Currency.value('CURRENCYCODE[1]', 'CHAR(3)'),
                Name = Currency.value('NAME[1]', 'NVARCHAR(50)'),
                Unit = Currency.value('UNIT[1]', 'INT'),
                Country = Currency.value('COUNTRY[1]', 'NVARCHAR(50)'),
                Rate = Currency.value('RATE[1]', 'DECIMAL(10, 4)'),
                Change = Currency.value('CHANGE[1]', 'DECIMAL(10, 4)')
        FROM    @XML.nodes('CURRENCIES/CURRENCY') c (Currency)
    )
    MERGE dbo.Currency cu
    USING C 
        ON C.LastUpdate = cu.LastUpdate
        AND C.CurrencyCode = cu.CurrencyCode
    WHEN MATCHED AND 
                C.Name != cu.Name 
            OR  C.Unit != cu.Unit
            OR  C.Country != cu.Country
            OR  C.Rate != cu.Rate
            OR  C.Change != cu.Change
        THEN UPDATE
        SET Name = C.Name,
            Unit = C.Unit,
            Country = C.Country,
            Rate = C.Rate,
            Change = C.Change
    WHEN NOT MATCHED THEN
        INSERT (LastUpdate, CurrencyCode, Name, Unit, Country, Rate, Change)
        VALUES (C.LastUpdate, C.CurrencyCode, C.Name, C.Unit, C.Country, C.Rate, C.Change);
然后,您只需调用您的过程来保存数据:

DECLARE @X XML = '<CURRENCIES>
                    <LAST_UPDATE>2014-01-30</LAST_UPDATE>
                    <CURRENCY><NAME>Dollar</NAME><UNIT>1</UNIT><CURRENCYCODE>USD</CURRENCYCODE><COUNTRY>USA</COUNTRY><RATE>3.492</RATE><CHANGE>0.057</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Pound</NAME><UNIT>1</UNIT><CURRENCYCODE>GBP</CURRENCYCODE><COUNTRY>Great Britain</COUNTRY><RATE>5.7575</RATE><CHANGE>-0.312</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Yen</NAME><UNIT>100</UNIT><CURRENCYCODE>JPY</CURRENCYCODE><COUNTRY>Japan</COUNTRY><RATE>3.4087</RATE><CHANGE>0.383</CHANGE></CURRENCY><CURRENCY><NAME>Euro</NAME><UNIT>1</UNIT><CURRENCYCODE>EUR</CURRENCYCODE><COUNTRY>EMU</COUNTRY><RATE>4.7492</RATE><CHANGE>-0.204</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Dollar</NAME><UNIT>1</UNIT><CURRENCYCODE>AUD</CURRENCYCODE><COUNTRY>Australia</COUNTRY><RATE>3.0620</RATE><CHANGE>0.219</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Dollar</NAME><UNIT>1</UNIT><CURRENCYCODE>CAD</CURRENCYCODE><COUNTRY>Canada</COUNTRY><RATE>3.1225</RATE><CHANGE>-0.24</CHANGE></CURRENCY>
                    <CURRENCY><NAME>krone</NAME><UNIT>1</UNIT><CURRENCYCODE>DKK</CURRENCYCODE><COUNTRY>Denmark</COUNTRY><RATE>0.6365</RATE><CHANGE>-0.188</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Krone</NAME><UNIT>1</UNIT><CURRENCYCODE>NOK</CURRENCYCODE><COUNTRY>Norway</COUNTRY><RATE>0.5602</RATE><CHANGE>-0.568</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Rand</NAME><UNIT>1</UNIT><CURRENCYCODE>ZAR</CURRENCYCODE><COUNTRY>South Africa</COUNTRY><RATE>0.3099</RATE><CHANGE>-1.054</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Krona</NAME><UNIT>1</UNIT><CURRENCYCODE>SEK</CURRENCYCODE><COUNTRY>Sweden</COUNTRY><RATE>0.5378</RATE><CHANGE>-0.407</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Franc</NAME><UNIT>1</UNIT><CURRENCYCODE>CHF</CURRENCYCODE><COUNTRY>Switzerland</COUNTRY><RATE>3.8827</RATE><CHANGE>0.072</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Dinar</NAME><UNIT>1</UNIT><CURRENCYCODE>JOD</CURRENCYCODE><COUNTRY>Jordan</COUNTRY><RATE>4.9370</RATE><CHANGE>0.032</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Pound</NAME><UNIT>10</UNIT><CURRENCYCODE>LBP</CURRENCYCODE><COUNTRY>Lebanon</COUNTRY><RATE>0.0232</RATE><CHANGE>0</CHANGE></CURRENCY>
                    <CURRENCY><NAME>Pound</NAME><UNIT>1</UNIT><CURRENCYCODE>EGP</CURRENCYCODE><COUNTRY>Egypt</COUNTRY><RATE>0.5016</RATE><CHANGE>0.06</CHANGE></CURRENCY>
                </CURRENCIES>';

EXECUTE dbo.SaveCurrencyXML @X;
您实际使用的是
String.Format
,即:

var sql = String.Format("Insert into History values('{0}','{1}','{2}','{3}','{4}')", date, id, "Deposit", amount, curr);
如果是,请立即停止。这是一种非常糟糕的做法,它不仅使您无法使用,而且每次都会强制重新编译查询,因为它无法使用。 另一个缺点是它不是强类型的,在您的查询中,假设
date
DateTime
类型,您会自动在此类型上调用
ToString()
方法,该方法将根据调用它的线程的区域性信息返回一个字符串,无法保证输出字符串的格式会被数据库识别为日期时间,因此如果目标列是日期时间,则会出现转换错误

相反,您应该使用参数化查询,但首先,尽管我怀疑您可能出于示例目的也缩短了查询,但在插入时最好将其缩短,这样您的最终查询将变成:

var sql = "INSERT History (Date, Id, Deposit, Amount, Curr) VALUES (@Date, @Id, @Deposit, @Amount, @Curr);";
然后需要将参数添加到
SqlCommand
,例如

var date = DateTime.Now;
command.Parameters.AddWithValue("@Date", date);
这意味着当发送到DB时,查询将把
@Date
视为DateTime(因为传递的值是DateTime),这意味着您的查询更安全

因此,对于您的示例,要调用上面的存储过程,您可以使用以下方法:

//using System.Xml;
//using System.Data.SqlClient;
//using System.Data.SqlTypes;

XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(@"YourXMLFile.xml");
using (var connection = new SqlConnection("ConnectionString"))
using (var command = new SqlCommand("dbo.SaveCurrencyXML", connection))
{
    var xml = new SqlXml(new XmlTextReader(xmldoc.InnerXml, XmlNodeType.Document, null));
    var param = new SqlParameter("@XML", SqlDbType.Xml).Value = xml;
    command.Parameters.Add(param);
    command.ExecuteNonQuery();
}

非常感谢您的展示。您使用的是哪一个数据库?我真的不知道如何开始,所以我没有尝试过任何东西,这是xml文件:,我使用的是sql server数据库(.mdf),非常感谢!我会尽快尝试,首先我想再次感谢您的帮助,但我无法理解这一点,在我的课堂上,我们使用c#中的microsoft web developer,当我们使用诸如“插入历史值({0}、{1}、{2}、{3}、{4}”)、日期、id、“存款”、金额、货币等查询时。那我应该把你给我的写在哪里?
var sql = "INSERT History (Date, Id, Deposit, Amount, Curr) VALUES (@Date, @Id, @Deposit, @Amount, @Curr);";
var date = DateTime.Now;
command.Parameters.AddWithValue("@Date", date);
//using System.Xml;
//using System.Data.SqlClient;
//using System.Data.SqlTypes;

XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(@"YourXMLFile.xml");
using (var connection = new SqlConnection("ConnectionString"))
using (var command = new SqlCommand("dbo.SaveCurrencyXML", connection))
{
    var xml = new SqlXml(new XmlTextReader(xmldoc.InnerXml, XmlNodeType.Document, null));
    var param = new SqlParameter("@XML", SqlDbType.Xml).Value = xml;
    command.Parameters.Add(param);
    command.ExecuteNonQuery();
}