7

行が存在する場合は更新され、存在しない場合は挿入されるように、MS-Access 2000 用の SQL クエリを作成する必要があります。(これは「アップサート」と呼ばれると思います)

すなわち

行が存在する場合...

UPDATE Table1 SET (...) WHERE Column1='SomeValue'

存在しない場合...

INSERT INTO Table1 VALUES (...)

これは 1 つのクエリで実行できますか?

4

6 に答える 6

12

クエリを使用して Access で upsert をシミュレートできます。UPDATELEFT JOIN

update b
left join a on b.id=a.id
set a.f1=b.f1
, a.f2=b.f2
, a.f3=b.f3
于 2016-05-03T20:42:44.410 に答える
7

Column1に一意のインデックスがあると仮定すると、式を使用して、 Column1 = 'SomeValue' のDCount行が 0 行か 1 行かを判断できます。次に、またはそのカウントに基づいて。INSERTUPDATE

If DCount("*", "Table1", "Column1 = 'SomeValue'") = 0 Then
    Debug.Print "do INSERT"
Else
    Debug.Print "do UPDATE"
End If

私は、最初に を試みINSERT、3022 キー違反エラーをトラップUPDATEし、エラーに応答して を実行するよりも、このアプローチを好みます。しかし、私のアプローチから大きな利益を得ることはできません。テーブルに autonumber フィールドが含まれている場合、failed を回避するINSERTと、次の autonumber 値を不必要に消費するのを防ぐことができます。INSERTまた、必要のない文字列を作成することを避けることもできます。Access Cookbookによると、VBA では文字列の連結はかなりコストのかかる操作なので、実際に必要でない限り、文字列の作成を避ける機会を探しています。このアプローチにより、不要な のロックの作成も回避されINSERTます。

ただし、これらの理由のいずれも、あなたにとって非常に説得力のあるものではない場合があります。そして、正直なところ、この場合の私の好みは、私にとって「正しいと感じる」ものであると思います。以前のスタック オーバーフローの質問に対する@ David-W-Fenton のコメントに同意します。データベースエンジンに頼って自分自身からあなたを救うのではなく、場所に置いてください。」

于 2011-06-01T15:58:06.090 に答える
3

通常、最初に挿入ステートメントを実行してから、行が既に存在することを示すエラー 3022 が発生したかどうかを確認します。だから、このようなもの:

On Error Resume Next
CurrentDb.Execute "INSERT INTO Table1 (Fields) VALUES (Data)", dbFailOnError
If Err.Number = 3022 Then
    Err.Clear        
    CurrentDb.Execute "UPDATE Table1 SET (Fields = Values) WHERE Column1 = 'SomeValue'", dbFailOnError
ElseIf Err.Number <> 0 Then
    'Handle the error here
    Err.Clear
End If

Edit1:
私がここに投稿したことは非常に一般的な解決策であることを述べたいと思いますが、エラーを計画し、プログラムの通常のフローの一部としてそれらを使用することは、一般的に悪い考えと見なされることに注意する必要があります。同じ結果を達成する他の方法。これを指摘してくれた RolandTumble に感謝します。

于 2011-06-01T11:49:03.637 に答える
3

エラーをキャッチする必要はありません。代わりに、INSERT ステートメントを実行してから確認してください。

CurrentDb.RecordsAffected

状況に応じて、1 または 0 になります。

注: CurrentDB に対して実行することはお勧めできません。データベースをローカル変数にキャプチャすることをお勧めします。

Dim db As DAO.Database
Set db = CurrentDb
db.Execute(INSERT...)
If db.RecordsAffected = 0 Then
  db.Execute(UPDATE...)
End If
于 2013-04-19T18:13:26.980 に答える