1

テーブルの配列 (文字列配列として格納) を使用してテーブルをループし、一連のクエリの削除/更新を実行するクエリがあります。クエリはテーブル名以外は同じであるため、ループを使用して、テーブル名を変数として使用して繰り返します。

問題は、私の削除クエリがテーブルをロックし、その後更新クエリの実行が速すぎることです。「データベースがロックされています」というエラーが表示されます。

次の 2 つのいずれかが必要です。

  1. VBAに「前のコマンドを待つ」ように指示する方法または
  2. これらのクエリを 1 つ (または 2 つ) のクエリに連結する方法: 1 つはデータベースの行を削除し、もう 1 つは新しい行をインポートします。これにより、標準アクセス クエリからクエリを実行することができます (適切な時間を割り当て、クエリを終了する必要があります)。

これに対する唯一の問題は、親子関係があることです。そのため、親テーブルはその子の前に更新する必要があります (現在、配列の順序付けによって実現されています)。

(時々)「DB locked/in use」メッセージを生成する現在のコードは次のとおりです。

For i = 0 To UBound(tables)
    'Delete all data first
    sql = "DELETE * FROM " & tables(i)
    DoCmd.RunSQL sql
    'Update all data second
    sql = "INSERT INTO " & tables(i) & " IN """ & toDB & """ SELECT " & tables(i) & " .* FROM " & tables(i) & " IN """ & fromDB & """;"
    DoCmd.RunSQL sql
Next

明確にする必要があります: クエリはfromDB、同一のテーブルから 1 つのバックエンドの ( ) 行を取得し、それを別のバックエンドの ( toDB) 行にプッシュします

編集: に関する質問に答えてINSERT INTO、私の問題は、フィールドを に追加すると、toDB上書きすると削除されることです。このバックドア アプローチを行う必要がある理由は、データベースがまだ開発中であり、選択テーブルでも使用されているためです。更新と機能の改善は毎日行われます。データベースにアクセスしている他のコンピューターが常にネットワーク上にあるとは限らないため (ネットワークに戻ったときに手動で同期する必要があります)、単純な分割バックエンドも使用できません。同一の(スキーマの更新を差し引いた)バックエンド。

4

4 に答える 4

2

DoCmd.RunSQL の代わりに ADO を使用して、SQL を同期的に実行できます。

 Dim cmd As ADODB.Command
 Dim cnn As New ADODB.Connection

 Set cnn = CurrentProject.Connection

 For i = 0 To UBound(tables)
     Set cmd = New ADODB.Command
     With cmd

        .CommandType = adCmdText
         .ActiveConnection = cnn
        .CommandText = "DELETE * FROM " & tables(i)
        .Execute
      End With

     Set cmd = New ADODB.Command
     With cmd

        .CommandType = adCmdText
         .ActiveConnection = cnn
        .CommandText = "INSERT INTO " & tables(i) & " IN """ & toDB & """ SELECT " & tables(i) & " .* FROM " & tables(i) & " IN """ & fromDB & """;"
        .Execute
      End With

Next

cnn.BeginTransandを追加cnn.CommitTransして、2 つのステートメントを Atomic にすることもできます。

于 2012-06-07T14:55:19.767 に答える
0

何かを待つ必要がある場合はDoEvents、保留にされた他のアクションをWindowsが処理できるようにするために使用する傾向があります。
ヘルプから:「オペレーティングシステムが他のイベントを処理できるように実行を生成します。」

これを見つけました:
.BeginTrans次に
.CommitTrans dbForceOSFlush
、続行する前に更新を強制的に書き込む方法として

于 2012-06-07T15:16:51.907 に答える
0

私は専門家ではありませんが、DELETE 部分は必要ないと思います。SELECT INTO は、テーブルを作成するための構文です。テーブルが既に存在する場合は、上書きされます。

于 2012-06-07T14:05:27.140 に答える