C# - 使用DataAdapter从DataTable更新SQL表 - > SQL表没有更新

时间:2011-11-17 17:33:11

标签: c# dataadapter rowstate

我从Excel电子表格中选择*到dt。我想获取这些值并更新SQL表。 (SQL表存在是因为从原始Excel电子表格手动导入到SQL,具有主键设置。用户更新excel表,我需要更新SQL值。)我将dt.RowState设置为已修改努力调用更新。我没有错误,但SQL表没有更新。 (以前的测试显示我的SQL权限和连接是好的,我可以修改表。)

connectionToSQL = new SqlConnection(SQLConnString);
                connectionToSQL.Open();


                var cmd = new SqlCommand("SELECT * FROM TAGS$",connectionToSQL);                 
                var da = new SqlDataAdapter(cmd);
                var b = new SqlCommandBuilder(da);


                foreach (DataRow r in dt.Rows)
                {
                    r.SetModified();
                }

                da.Update(dt);   

3 个答案:

答案 0 :(得分:7)

试试这个......

using System.Data;
using System.Data.SqlClient;
using System;
namespace Q308507 {

class Class1 
{
  static void Main(string[] args)   
  {

    SqlConnection cn = new SqlConnection();
    DataSet CustomersDataSet = new DataSet();
    SqlDataAdapter da;
    SqlCommandBuilder cmdBuilder;

    //Set the connection string of the SqlConnection object to connect
    //to the SQL Server database in which you created the sample
    //table.
    cn.ConnectionString = "Server=server;Database=northwind;UID=login;PWD=password;";
    cn.Open();      

    //Initialize the SqlDataAdapter object by specifying a Select command 
    //that retrieves data from the sample table.
    da = new SqlDataAdapter("select * from CustTest order by CustId", cn);

    //Initialize the SqlCommandBuilder object to automatically generate and initialize
    //the UpdateCommand, InsertCommand, and DeleteCommand properties of the SqlDataAdapter.
    cmdBuilder = new SqlCommandBuilder(da);

    //Populate the DataSet by running the Fill method of the SqlDataAdapter.
    da.Fill(CustomersDataSet, "Customers");

    //Display the Update, Insert, and Delete commands that were automatically generated
    //by the SqlCommandBuilder object.
    Console.WriteLine("Update command Generated by the Command Builder : ");
    Console.WriteLine("==================================================");
    Console.WriteLine(cmdBuilder.GetUpdateCommand().CommandText);
    Console.WriteLine("         ");

    Console.WriteLine("Insert command Generated by the Command Builder : ");
    Console.WriteLine("==================================================");
    Console.WriteLine(cmdBuilder.GetInsertCommand().CommandText);
    Console.WriteLine("         ");        

    Console.WriteLine("Delete command Generated by the Command Builder : ");
    Console.WriteLine("==================================================");
    Console.WriteLine(cmdBuilder.GetDeleteCommand().CommandText);
Console.WriteLine("         ");

    //Write out the value in the CustName field before updating the data using the DataSet.
    Console.WriteLine("Customer Name before Update : " + CustomersDataSet.Tables["Customers"].Rows[0]["CustName"]);

    //Modify the value of the CustName field.
    CustomersDataSet.Tables["Customers"].Rows[0]["CustName"] = "Jack";

    //Post the data modification to the database.
    da.Update(CustomersDataSet, "Customers");        

    Console.WriteLine("Customer Name updated successfully");

    //Close the database connection.
    cn.Close();

    //Pause
    Console.ReadLine();
   }
 }
}

答案 1 :(得分:2)

我认为由SqlCommandBuilder生成的自动生成的SqlCommands实际上并不适合你的情况(如果我已经正确理解了这个问题)。在SqlCommandBuilder生成的SQL Update语句的WHERE子句中,将ALL列的值与其原始值进行比较(由DataRow中的原始数据值确定)。如果目标数据库中的原始值不匹配,则不会更新任何行。

这个指向SqlCommandBuilder的链接可能有所帮助:

http://msdn.microsoft.com/en-us/library/ms971491.aspx

从该链接,尝试理解:“adCriteriaAllCols”,因为这是SqlCommandBuilder使用的。我怀疑你想要的是“AdCriteriaKey”行为。

一种可能的解决方案可能是不使用SqlCommandBuilder,只需自己编写INSERT / UPDATE / DELETE SqlCommands,并将它们附加到SqlDataAdapter.InsertCommand,UpdateCommand和DeleteCommand。 在http://support.microsoft.com/kb/308055

上有一些示例代码

编辑:.net版本2.0及更高版本中的SqlCommandBuilder具有ConflictOption属性。使用的默认值是:CompareAllSearchableValues。尝试使用:OverwriteChanges,这将导致在SQL语句中生成的WHERE子句仅比较主键值。

答案 2 :(得分:1)

我试过评论,但被告知要重新阅读这个问题。所以我做了,并没有帮助:)你在这个例子中只有很少的代码将dt(你说这是从Excel填充)与数据库联系在一起。您有变量connectionToSQLcmddab。它们连接到数据库。然后迭代dt,而不是。这就是为什么在我的评论中我要求你在dt中修改行的示例源代码 - 因为我假设你会在某个地方使用它,以便期望更改会从Excel(填充dt)跳转到您的数据库。

我看到您正在调用da.Update(dt);尝试从数据库中打开一个新数据集,然后浏览dt中的行,将更改应用于新数据集中的行。从我所知道的 - 那里没有太多代码 - 没有发出命令,因为dataadapter知道dt的内部行不是来自它的数据源。无论如何,这是我的准备。