2011-01-30 17 views
0

この問題は説明するのが難しいですが、ここでは説明します。私は、ローカルのSQLiteDatabaseからオンラインでMySQLデータベースにレコードを追加する関数を持っています。関数が最初に呼び出されてローカルデータが取得され、各行はアップロード関数に送られ、レコードがオンラインMySQLデータベースに追加されます。これらの関数が別の関数Aから呼び出されると、別の関数から呼び出されたときにうまく動作します。機能B重複レコードがデータベースに入力されます。データベース内で重複したレコードが原因でコード自体が繰り返されています

問題を解決するためのデバッグ中に、レコードを複製しているときにcmd.executeNonQuery()に行き、次の行に移動しますが、何も理由がないためcmd.executeNonQuery ()はレコードを複製します。コードは

private void uploadDatabase(string company, string oldCompany, string companyURL, string loginUsername, string oldUsername, string password, string type, string perform, string direction) 
     { 
      Boolean recordFound = false; 
      recordFound = checkRecordNotExist(company, loginUsername); 
      MySQLDBWork dbase = new MySQLDBWork(); 
      try 
      { 
       dbase.openConnection(); 
       if (perform == "insert" && !recordFound) 
       { 
        string query = "INSERT INTO `" + username + "` (pas_company, pas_companyURL, pas_username, pas_password, pas_type) " 
         + "VALUES ('" + company + "', '" + companyURL + "', '" + loginUsername + "', '" + password + "', '" + type + "')"; 
        Console.WriteLine("Query: " + query); 
        MySqlCommand cmd = new MySqlCommand(query, dbase.conn); 
        cmd.ExecuteNonQuery(); 
        recordFound = true; 
        query = ""; 
        company = ""; 
        loginUsername = ""; 
        cmd.Dispose(); 
       } 
       if (perform == "delete") 
       { 
        string query = "DELETE FROM `" + username + "` WHERE pas_company='" + company + "' AND pas_username='" + loginUsername + "'"; 
        dbase.performQuery(query); 
       } 
      } 
      catch (MySqlException ex) 
      { 
       Console.WriteLine("Adding Online Error: " + ex.Message); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("General Exception: " + ex.Message); 
      } 
      finally 
      { 
       dbase.closeConnection(); 
       //dbase.conn.Dispose(); 
       company = null; 
       loginUsername = null; 
      } 
     } 

を下回っている文は== & &「を挿入」を実行する場合、問題は以内です!recordFound。

上記のコードが問題の解決に役立つかどうかは分かりませんが、これは関数bから呼び出されたときに間違っている関数ですが、関数Aからうまく機能します。ご協力いただきありがとうございます。

+0

(1)最新のソースを使用していますか(再構築が役立つかもしれません)、(2)デバッグ、アプリケーションのリリースバージョンをデバッグしていますか? – Vlad

答えて

3

当時)(ライン の次のカップルに行くが、その後何の理由もなく、最大 cmd.executeNonQueryに戻ります

簡単なマルチスレッドの問題のように聞こえること。この関数は別のスレッドから再度アクセスされます。つまり、両方のスレッドでチェックが行われてからどちらかに挿入されると、その両方に挿入されます。だから、

、ロックを作成し、コードをロック...このような何か:

private System.Object uploadLock = new System.Object(); 

private void uploadDatabase(string company, string oldCompany, string companyURL, string loginUsername, string oldUsername, string password, string type, string perform, string direction) 
     { 
      lock(uploadLock) { 
      Boolean recordFound = false; 
      recordFound = checkRecordNotExist(company, loginUsername); 
      MySQLDBWork dbase = new MySQLDBWork(); 
      try 
      { 
       dbase.openConnection(); 
       if (perform == "insert" && !recordFound) 
       { 
        string query = "INSERT INTO `" + username + "` (pas_company, pas_companyURL, pas_username, pas_password, pas_type) " 
         + "VALUES ('" + company + "', '" + companyURL + "', '" + loginUsername + "', '" + password + "', '" + type + "')"; 
        Console.WriteLine("Query: " + query); 
        MySqlCommand cmd = new MySqlCommand(query, dbase.conn); 
        cmd.ExecuteNonQuery(); 
        recordFound = true; 
        query = ""; 
        company = ""; 
        loginUsername = ""; 
        cmd.Dispose(); 
       } 
       if (perform == "delete") 
       { 
        string query = "DELETE FROM `" + username + "` WHERE pas_company='" + company + "' AND pas_username='" + loginUsername + "'"; 
        dbase.performQuery(query); 
       } 
      } 
      catch (MySqlException ex) 
      { 
       Console.WriteLine("Adding Online Error: " + ex.Message); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("General Exception: " + ex.Message); 
      } 
      finally 
      { 
       dbase.closeConnection(); 
       //dbase.conn.Dispose(); 
       company = null; 
       loginUsername = null; 
      } 
     } 
} 

ロックは、一度にスレッド上にコードへのアクセスを許可します。だから、重複はありません。

0

cmd.ExecuteNonQuery();にブレークポイントを設定し、ヒットするたびにcall stackを検査することをお勧めします.2回目/重複したヒットに特に注意してください。また、ブレークポイントがヒットしているwhich threadにも注意してください。これらのことをすることはあなたに問題を指摘するはずです。あなたに

2

は私のアドバイス:

  • は常にトランザクションを使用して、重複を作ることができません。 LoginName列を一意にし、dbエラーを適切に処理することもできます。
  • 文字列を連結してクエリを作成しないでください。コマンド・パラメーターを使用する - 最も簡単な方法でSQLインジェクションをエスケープします。現在、少なくとも4つの脆弱なパラメータがあります。
関連する問題