2010-11-24 8 views
0

テーブル内の特定のGUIDを、ユーザーが指定するGUIDに変更するプログラムを作成しようとしています。それはそれは私に次のエラーを与える新しいものと古いGUIDを上書きしようとすると 問題がある:C#でデータベース内のフィールドを更新する際に問題が発生する

You cannot add or change a record because a related record is required in table tblEF

データベースには、5つのテーブルを持っています。メインテーブルtblAには、プライマリキーがpkAccountsに設定されています。他のテーブルにはすべて、fkAccountsという外部キーがあります。

すべてのリレーションシップは、参照整合性を強制し、カスケード関連レコードを削除するように設定されています。手動でデータベースを開き、関連するフィールドをカスケード更新するように関係を編集すると、プログラムはGUIDを更新しますが、データベースが使用されているプログラムは機能しなくなります。

これを克服しようとすると、メインテーブルのプライマリキーを削除する変数に追加し、プログラムがすべてのGUIDを置き換えた後にプライマリキーを戻します。この場合、変更表の構文エラー

ここに私のコードです。申し訳ありませんが、それは乱雑ですが、これは私の最初のプログラムの一つです。プラス私の最初の時間は、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フィールドを編集できますか?

+1

これはあなたの質問には対処しませんが、そのような更新クエリを作成することで、SQLインジェクション攻撃までアプリを開いていることを知っておく必要があります。後で潜在的な頭痛を避けるために準備されたステートメントを使用してください:) –

答えて

0

制約を削除する代わりに、テーブルに新しい行を追加してデータをコピーするだけです。

  1. ユーザーが望むGUIDを持つ新しい行を挿入します。
  2. 次に、古い行のデータで行を更新します。
  3. 変更し、新しい行へのすべての外部キー参照
+0

母、私は間違った方法でそれについて行っていた。そして再び、私はちょうど出発しています。ありがとう! – NewShinyCD

0

「UserEnteredGuid」という列を追加し、値がある時はいつでも、ユーザーの代わりに、本当 GUIDにそれを表示する古い行を削除します。 nullではありません。これは本当に唯一の純粋なアプローチです。

通常、主キーは変更されない値です。

+0

または、このGUIDのフィールドが、主キーとしてまったく使用されていない完全に別のフィールドを持つ。 – Giraffe

関連する問題