2008-10-03 24 views
17

Trong Oracle, được đưa ra một bảng dữ liệu đơn giản:Oracle sáp nhập hằng vào bảng duy nhất

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

cho rằng tôi muốn "chèn hoặc cập nhật" một giá trị. Tôi có một cái gì đó như:

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'); 

Có cách nào tốt hơn? Lệnh này dường như có những hạn chế sau:

  • Mỗi nhu cầu đen được gõ hai lần (hoặc thêm hai lần thông qua thiết lập thông số)
  • Các "bằng kép" cú pháp dường như hacky

Nếu đây là cách tốt nhất, có cách nào xung quanh phải thiết lập mỗi tham số hai lần trong JDBC?

+0

Nếu bạn đang sử dụng 10g, "DUAL" thậm chí còn ít bị hack hơn. trước đó nó là một cái bàn thật, trong 10g nó không phải. –

Trả lời

18

Tôi không xem xét sử dụng chế độ kép là hack. Để loại bỏ ràng buộc/nhập hai lần, tôi sẽ làm điều gì đó như:

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); 
-4

Sử dụng một thủ tục lưu trữ

4

tôi sẽ giấu MERGE bên trong một SQL API/PL và sau đó gọi đó thông qua JDBC:

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

Để thay thế cho MERGE, API có thể làm:

begin 
    insert into data (...) values (...); 
exception 
    when dup_val_on_index then 
     update data 
     set ... 
     where ...; 
end; 
2

Tôi muốn thử cập nhật trước khi chèn để lưu phải kiểm tra ngoại lệ.

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

if sql%notfound then 

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

end if; 

Ngay cả bây giờ chúng tôi có tuyên bố hợp nhất, tôi vẫn có xu hướng cập nhật hàng đơn theo cách này - dường như có nhiều cú pháp tự nhiên hơn. Tất nhiên, hợp nhất thực sự đi vào riêng của nó khi giao dịch với các tập dữ liệu lớn hơn.

+1

Tôi nghĩ rằng bạn đúng rằng nó có vẻ là một cú pháp tự nhiên hơn, nhưng tôi thích cách tiếp cận đơn giao dịch của bản thân hợp nhất - không có cơ hội của bất cứ điều gì không xảy ra giữa cập nhật và chèn. –

+0

Không có sự cố nào có thể xảy ra giữa bản cập nhật và phần chèn - đây là chế độ xem giao dịch nhất quán của Oracle. –

+0

Cú pháp này có hoạt động trong oracle9i không? –

0

Khi nguồn và bảng đích của bạn giống nhau, bạn cần sử dụng DUAL.

Các vấn đề liên quan