20

Oracle では、単純なデータ テーブルが与えられます。

create table data (
    id       VARCHAR2(255),
    key      VARCHAR2(255),
    value    VARCHAR2(511));

値を「挿入または更新」したいとします。私は次のようなものを持っています:

merge into data using dual on 
    (id='someid' and key='testKey')
when matched then 
    update set value = 'someValue' 
when not matched then 
    insert (id, key, value) values ('someid', 'testKey', 'someValue');

これよりも良い方法はありますか?このコマンドには、次の欠点があるようです。

  • すべてのリテラルは 2 回入力する必要があります (またはパラメーター設定で 2 回追加する必要があります)。
  • 「デュアルを使用する」構文はハックのようです

これが最善の方法である場合、JDBC で各パラメーターを 2 回設定する必要があることを回避する方法はありますか?

4

3 に答える 3

23

デュアルの使用をハックとは考えていません。バインディング/タイピングを 2 回行う必要がないようにするには、次のようにします。

merge into data
using (
    select
        'someid' id,
        'testKey' key,
        'someValue' value
    from
        dual
) val on (
    data.id=val.id
    and data.key=val.key
)
when matched then 
    update set data.value = val.value 
when not matched then 
    insert (id, key, value) values (val.id, val.key, val.value);
于 2008-10-03T16:29:38.143 に答える
4

PL/SQL API 内に MERGE を隠し、それを JDBC 経由で呼び出します。

data_pkg.merge_data ('someid', 'testKey', 'someValue');

MERGE の代わりに、API で次のことができます。

begin
   insert into data (...) values (...);
exception
   when dup_val_on_index then
      update data
      set ...
      where ...;
end;
于 2008-10-03T15:48:07.510 に答える
2

例外をチェックする必要がないように、挿入の前に更新を試みることをお勧めします。

update data set ...=... where ...=...;

if sql%notfound then

    insert into data (...) values (...);

end if;

今でもmergeステートメントがありますが、私はまだこの方法で単一行の更新を行う傾向があります-より自然な構文のようです. もちろん、マージは、より大きなデータ セットを処理する場合に真価を発揮します。

于 2008-10-03T19:45:28.607 に答える