【问题标题】:Trouble updating fields in a database with C#使用 C# 更新数据库中的字段时遇到问题
【发布时间】:2010-11-24 23:04:56
【问题描述】:

我正在尝试编写一个程序,它将表中的特定 GUID 更改为用户指定的 GUID。 问题是当它试图用新的 GUID 覆盖旧的 GUID 时,它会给我以下错误:

您不能添加或更改记录 因为需要相关记录 在表 tblEF 中

数据库有 5 个表。主表 tblA 的主键设置为 pkAccounts。其他表都有一个外键,称为 fkAccounts。

所有关系都设置为强制参照完整性和级联删除相关记录。如果我手动打开数据库并编辑关系以具有级联更新相关字段,我的程序将更新 GUID,但使用数据库的程序将不再工作。

为了克服这个问题,我添加了一些变量,这些变量会删除主表上的主键,然后在程序完成替换所有 GUID 后重新添加主键。在这种情况下,我会得到 Alter Table 中的语法错误

这是我的代码。对不起,如果它很乱,但这是我的第一个程序之一。加上我第一次搞砸 SQL 的东西。

try
 {
   string GetRI = "SELECT fkAccountGUID FROM tblR";
   string GetTWI = "SELECT pkAccountGUID FROM tblTW";
   string GetAI = "SELECT pkAccountGUID FROM tblA";
   string GetEAI = "SELECT fkAccountGUID FROM tblEAI";
   string GetEF = "SELECT fkAccountGUID FROM tblEF";
   string NoPK = "ALTER TABLE tblA DROP CONSTRAINT pkAID";
   string PK = "ALTER TABLE tblA ADD PRIMARY KEY (pkAID)";

   DataSet ds = new DataSet();

   //create a connection to the database
       OleDbConnection ConnectDatabase = new OleDbConnection(
           "Provider=Microsoft.Jet.OLEDB.4.0;" +
           @"Data Source=C:\db.mdb;" +
           "Persist Security Info=True;" +
           "Jet OLEDB:Database Password=123;");

   //open the connection to the database
   ConnectDatabase.Open();

   //creates an adapter and runs the string command from the database connection
   //it will then fill the information in the dataset in its own table
   OleDbDataAdapter DatabaseAdapter = new OleDbDataAdapter(GetRI, ConnectDatabase);
   DatabaseAdapter.Fill(ds, "tblR");
   OleDbDataAdapter DatabaseAdapter1 = new OleDbDataAdapter(GetAI, ConnectDatabase);
   DatabaseAdapter.Fill(ds, "tblA");
   OleDbDataAdapter DatabaseAdapter2 = new OleDbDataAdapter(GetTWI, ConnectDatabase);
   DatabaseAdapter.Fill(ds, "tblTW");
   OleDbDataAdapter DatabaseAdapter3 = new OleDbDataAdapter(GetEAI, ConnectDatabase);
   DatabaseAdapter.Fill(ds, "tblEAI");
   OleDbDataAdapter DatabaseAdapter4 = new OleDbDataAdapter(GetEF, ConnectDatabase);
   DatabaseAdapter.Fill(ds, "tblEF");

   //get old GUID
   Console.WriteLine("What is the current GUID?");
   string OldGUID = Console.ReadLine();
   char ap = '\x0027';
   OldGUID = ap + OldGUID + ap;

   //get new GUID
   Console.WriteLine("What is the new GUID name?");
   string NewGUID = Console.ReadLine();
   NewGUID = ap + NewGUID + ap;

   //test lines
   //Console.WriteLine(NewGUID);
   //Console.WriteLine(OldGUID);

   //UPDATE string to rename the old GUID to the New GUID
   string UpdateR = "UPDATE tblR SET fkAccountGUID=" + NewGUID + "WHERE fkAccountGUID=" + OldGUID;
   string UpdateA = "UPDATE tblA SET pkAccountGUID=" + NewGUID + "WHERE pkAccountGUID=" + OldGUID;
   string UpdateTW = "UPDATE tblTW SET pkfkAccountGUID=" + NewGUID + "WHERE pkfkAccountGUID=" + OldGUID;
   string UpdateEA = "UPDATE tblTW SET fkAccountGUID=" + NewGUID + "WHERE fkAccountGUID=" + OldGUID;
   string UpdateEF = "UPDATE tblEF SET fkAccountGUID=" + NewGUID + "WHERE fkAccountGUID=" + OldGUID;

   //create the variables to run the string commands
   OleDbCommand updatecmd0 = new OleDbCommand(UpdateF);
   OleDbCommand updatecmd1 = new OleDbCommand(UpdateR);
   OleDbCommand updatecmd2 = new OleDbCommand(UpdateEA);
   OleDbCommand updatecmd3 = new OleDbCommand(UpdateTW);
   OleDbCommand updatecmd4 = new OleDbCommand(UpdateA);
   OleDbCommand nocheckcmd = new OleDbCommand(NoPK);
   OleDbCommand checkcmd = new OleDbCommand(PK);

   //have the commands connect to the database
   nocheckcmd.Connection = ConnectDatabase;
   updatecmd0.Connection = ConnectDatabase;
   updatecmd1.Connection = ConnectDatabase;
   updatecmd2.Connection = ConnectDatabase;
   updatecmd3.Connection = ConnectDatabase;
   updatecmd4.Connection = ConnectDatabase;
   checkcmd.Connection = ConnectDatabase;

   //Run the commands
   nocheckcmd.ExecuteNonQuery();
   updatecmd0.ExecuteNonQuery();
   updatecmd1.ExecuteNonQuery();
   updatecmd2.ExecuteNonQuery();
   updatecmd3.ExecuteNonQuery();
   updatecmd4.ExecuteNonQuery();
   checkcmd.ExecuteNonQuery();

   //Dispose the adapter and close the connection to the database.
   DatabaseAdapter.Dispose();
   ConnectDatabase.Close();

   //console will display the string if everything completed
   Console.WriteLine("Success. Press any key to exit.");
   Console.Read();

 }
catch (OleDbException Error)
 {
   //when an error occurs display the error in the console
   Console.WriteLine(Error.Message);
   Console.Read();
 }

基本上,如何在不手动打开数据库检查级联更新,运行我的程序,然后再次打开数据库并取消选中级联更新的情况下编辑 5 个数据库中的 GUID 字段?

【问题讨论】:

  • 这并不能解决您的问题,但您应该知道,通过构建类似的更新查询,您的应用程序将面临 SQL 注入攻击。使用准备好的语句来避免以后可能出现的问题:)

标签: c# sql database visual-studio


【解决方案1】:

无需删除约束,只需向表中添加新行并复制数据即可。

  1. 使用用户想要的 GUID 插入新行。
  2. 然后使用旧行中的数据更新该行。
  3. 将所有外键引用更改为新行
  4. 删除旧行

【讨论】:

  • 哈哈,我走错路了。再说一次,我才刚刚开始。谢谢!
【解决方案2】:

添加一个名为“UserEnteredGuid”的列,并在值不为空时将其显示给用户,而不是 real GUID。这确实是唯一明智的方法。

通常,主键是永远不会修改的值。

【讨论】:

  • 或者,为此 GUID 有一个完全独立的字段,根本不用作主键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多