2017-04-24 5 views
2

ローカルデータベースを他のデータベースデータで更新するルーチンがあります。SELECTが返されたときにのみDELETEを実行

Iのみを削除してから、以下のようにINSERT INTO tblX((tblYリンクテーブルである)tblY SELECT * FROM)、実行します。

問題はとI'dを削除した後、いくつかのケースではSELECTは長い時間がかかる、ということであるがit's処理中に、このテーブルに要求を行うユーザの可能性を減少したいです。

I'dはのみSELECTの復帰後をDELETE実行するためのいくつかのメカニズムがあるかどうかを知りたいです。

conn = new OleDbConnection(Conexao.getConexaoPainelGerencialLocal()); 

conn.Open(); 

OleDbCommand cmd = new OleDbCommand(" DELETE * FROM tblClienteContato; ", conn); 

cmd.ExecuteNonQuery(); 

cmd = new OleDbCommand(" INSERT INTO tblClienteContato " + 
         " SELECT * FROM tblClienteContatoVinculada;", conn); 

cmd.ExecuteNonQuery(); 

答えて

0

グレッグがコメントしたように、私は外部データベースからデータを受信するために一時テーブルを作成し、影響を受けて、ユーザの確率は非常に低くなるように、私は、決定的なテーブルにデータをtranfer。

2

あなたがする必要があるのは、これらのコマンドを両方ともトランザクション内にラップすることです。

取引についての涼しい事は、それがALLは何かがselect文を停止してしまった場合、データベースはdelete文を確定しないことを意味し、またはALLはに失敗ワークスのどちらかということです。

これはで動作するように本当に良い例のようになります。彼らは1つのコマンドオブジェクトを持っている、とのCommandTextを置き換えるのではなく、新しいオブジェクトを毎回作成すること https://msdn.microsoft.com/en-us/library/93ehy0z8(v=vs.110).aspx

注意を。これはおそらく重要です。

はこのような何かを試してみてください:

conn = new OleDbConnection(Conexao.getConexaoPainelGerencialLocal()); 
OleDbCommand cmd = new OleDbCommand(); 
OleDbTransaction transaction = null; 

try { 

    conn.Open(); 
    transaction = conn.BeginTransaction(IsolationLevel.ReadCommitted); 

    cmd.Connection = conn; 
    cmd.Transaction = transaction; 



    cmd.CommandText = " DELETE * FROM tblClienteContato; "; 
    cmd.ExecuteNonQuery(); 

    cmd.CommandText = " INSERT INTO tblClienteContato " + 
         " SELECT * FROM tblClienteContatoVinculada;"; 

    cmd.ExecuteNonQuery(); 

    // The data isn't _finally_ completed until this happens 
    transaction.Commit(); 


} 
catch (Exception ex) 
{ 
    // Something has gone wrong. 
    // do whatever error messaging you do 
    Console.WriteLine(ex.Message); 
    try 
    { 
     // Attempt to roll back the transaction. 
     // this means your records won't be deleted 
     transaction.Rollback(); 
    } 
    catch 
    { 
     // Do nothing here; transaction is not active. 
    } 
} 
+0

Greg、 "BeginTransaction"を実行しているときに次のメッセージが表示されます: "分離レベルも強化もサポートされていません" – User

+0

パラメータはありませんか?アクセスとジェットはおそらく分離レベルをサポートしていません。 – GregHNZ

+0

別のオプションは、一時テーブルを使用して2つの段階でこれを行うことです。 (誰も使用していない)テンポラリテーブルからのDELETEを実行するには、遅いINSERTをテンポラリテーブルに入れます。これが完了すると、メインテーブルからDELETEし、INSERTをメインテーブルに行いますが、リモートのテーブルではなくローカルテンポラリテーブル(高速である必要があります)から選択します。これは、メインテーブルがビジーである時間がはるかに短くなければならないことを意味します。 – GregHNZ

0

あなたは、でBeginTransactionに見コミットとロールバックする必要があり、ここでの例です:

_con.Open(); 
    _con_trans = _con.BeginTransaction(); 
    using(SqlCommand cmd = _con.CreateCommand()) 
    { 
     cmd.CommandText = "delete from XXXXX"; 
     cmd.CommandType = CommandType.Text; 
     cmd.Transaction = _con_trans; 
     cmd.ExecuteNonquery(); 
    } 

    using(SqlCommand cmd = _con.CreateCommand()) 
    { 
     cmd.CommandText = "insert into XXXX"; 
     cmd.CommandType = CommandType.Text; 
     cmd.Transaction = _con_trans; 
     cmd.ExecuteNonquery(); 
    } 
    _con_trans.Commit(); 
    _con_trans = null; 
    _con.Close(); 

この方法では、すべてが単一のトランザクションの下で包まれ、その時にされます削除が開始されると、テーブルは読み書きのためにロックされます。

+0

アレックス、 "BeginTransaction"を実行するときに次のメッセージが表示されます: "分離レベルも強化もサポートされていません" – User

0

テーブルのスキーマを知らなくても、削除処理に長時間かかる理由を特定するのは難しいです。

トランザクション内でコマンドをラップする代わりに、DROP TABLEコマンドを使用して、その中のデータではなく単にテーブル自体を削除することもできます。そして、再作成するためにSELECT...INTO...FROMステートメントを利用してテーブルを再作成することができます。これに潜在的な利点は、スキーマが同じに一致し、固有の変換(例えば、10進数から整数)を実行する必要がないことです。

using (conn = new OleDbConnection(Conexao.getConexaoPainelGerencialLocal())) { 
     conn.Open(); 

     using (OleDbCommand cmd = new OleDbCommand()) { 
      cmd.CommandText = "DROP TABLE tblClienteContato; "; 
      cmd.ExecuteNonQuery(); 

      cmd.CommandText = "SELECT * INTO tblClienteContato FROM tblClienteContatoVinculada;"; 
      cmd.ExecuteNonQuery(); 
     } 
    } 

次はここ(MSアクセス)は適用されないかもしれないが、別のオプション 他のSQLバリアントには、一挙にテーブル内のすべてのものを削除しますTRUNCATEコマンドを利用することです。個々の行のログはなく、索引(存在する場合)は、削除される行ごとに再計算する必要はありません。このメソッドへのキャッチは、これがトランザクション内では機能しないことです。 ID列がある場合、値もリセットされます。これには他の潜在的な短所がありますが、私はそれらを識別する方法がないテーブルの設計を知らないと。

using (conn = new OleDbConnection(Conexao.getConexaoPainelGerencialLocal())) { 
    conn.Open(); 
    using (OleDbCommand cmd = new OleDbCommand()) { 

     cmd.CommandText = "TRUNCATE TABLE tblClienteContato; "; 
     cmd.ExecuteNonQuery(); 

     cmd.CommandText = " INSERT INTO tblClienteContato " + 
      " SELECT * FROM tblClienteContatoVinculada;"; 
     cmd.ExecuteNonQuery(); 
    } 
} 
+0

Mad、遅延の問題が続いていますselectコマンド テーブルからデータを削除した後、選択に新しい日付を取得するまでに時間がかかります。 – User

+0

これをMS Access内で実行するとどうなりますか? –

関連する問題