2012-07-27 56 views
6

Tôi hiện đang viết các câu lệnh cập nhật để giữ cho bảng có thể truy vấn được cập nhật liên tục. Giản đồ là giống hệt nhau giữa hai bảng và các nội dung không phải là quan trọng:Cập nhật Oracle SQL dựa trên truy vấn phụ giữa hai bảng

STAGING 

ID 
NAME 
COUNT  

PRODUCTION 

ID 
NAME 
COUNT 

báo cáo cập nhật của tôi trông như sau:

update PRODUCTION 
set name = (select stage.name from staging stage where stage.name=name and rownum <2), 
    count = (select stage.countfrom staging stage where stage.count=count and rownum <2); 

Hai điều đáng chú ý được rằng 1) Có không là mệnh đề where tại kết thúc cập nhật của tôi (điều này có thể là vấn đề) và 2) tất cả các bản ghi sau khi được cập nhật có cùng giá trị. Những gì tôi có ý nghĩa bởi đây là những điều sau đây:

BEFORE UPDATE: 

1,"JOHN", 12; 
2,"STEVE",15; 
3,"BETTY",2; 

AFTER UPDATE 

    1,"JOHN", 12; 
    2,"JOHN",12; 
    3,"JOHN",12; 

Câu hỏi của tôi là làm thế nào để tôi sửa lỗi này để các bảng đúng phản ánh "mới" dữ liệu từ dàn dựng như một bản cập nhật SQL có đúng không?

CẬP NHẬT

Vì vậy, dữ liệu dàn tôi tình cờ có thể phản ánh những gì có trong PRODUCTION và vì lợi ích của cuộc thảo luận nó sẽ:

STAGING DATA TO MERGE: 

    1,"JOHN", 12; 
    2,"STEVE",15; 
    3,"BETTY",2; 

CẬP NHẬT thứ hai

Các truy vấn mà Tôi muốn chạy sẽ là:

update PRODUCTION 
set production.name = staging.name, 
    production.count = staging.count 

where production.name = staging.name; 

Tuy nhiên, điều này dẫn đến các vấn đề về số nhận dạng không hợp lệ trên "staging.name"

+0

Bạn có muốn giữ ** tên ** và ** tính ** trong ** SẢN XUẤT ** bảng cập nhật và bảng ** STAGING ** đang thay đổi không? – hmmftg

+0

Tại sao bạn không sử dụng trình kích hoạt để chèn các giá trị mới thay vì cập nhật này? cập nhật này chính xác là gì? – hmmftg

+0

Đồng ý, khi đồng bộ hóa bảng, trình kích hoạt có thể thực sự hữu ích trong việc giữ cho chúng được cập nhật theo thời gian thực. Chỉ cần xem ra để thay đổi các lỗi bảng, và chắc chắn để làm điều đó như là một sau khi INSERT hoặc UPDATE. – Hermit

Trả lời

26

Có hai cách để làm những gì bạn đang cố gắng

Một là Multi-column Correlated Update

UPDATE PRODUCTION a 
SET (name, count) = (
    SELECT name, count 
    FROM STAGING b 
    WHERE a.ID = b.ID); 

DEMO

Bạn có thể sử dụng merge

MERGE INTO PRODUCTION a 
USING (select id, name, count 
      from STAGING) b 
ON (a.id = b.id) 
WHEN MATCHED THEN 
UPDATE SET a.name = b.name, 
      a.count = b.count 

DEMO

+0

Hãy để tôi thử đa cột tương quan. Tôi phải rời khỏi hợp nhất vì nó bị chậm (hơn 10 triệu bản ghi) – Woot4Moo

0

Như bạn đã nhận thấy, bạn không có lựa chọn nào cho bản cập nhật của mình để cập nhật toàn bộ bảng. Nếu bạn muốn cập nhật các hàng cụ thể (ví dụ: nơi các ID phù hợp), bạn có thể muốn thực hiện truy vấn con được phối hợp.

Tuy nhiên, vì bạn đang sử dụng Oracle, có thể dễ dàng hơn để tạo chế độ xem được thực hiện cho bảng truy vấn của bạn và cho phép cơ chế giao dịch của Oracle xử lý các chi tiết. MV hoạt động chính xác như bảng để truy vấn ngữ nghĩa, khá dễ thiết lập và cho phép bạn chỉ định khoảng thời gian làm mới.

1

Không có ví dụ về tập dữ liệu dàn dựng này là ảnh trong bóng tối, nhưng bạn đã thử một cái gì đó như thế này chưa?

update PRODUCTION p, 
     staging s 
set p.name = s.name 
    p.count = s.count 
where p.id = s.id 

Điều này sẽ hoạt động giả định cột id khớp trên cả hai bảng.

+0

Vì vậy, nếu những điều duy nhất mà tôi muốn phù hợp trên là những điều khoản trong các truy vấn phụ của tôi? IE đặt blah ở đâu p.name = s.name và p.count = s.count? – Woot4Moo

+0

Nếu bạn đã làm điều đó, bạn sẽ được thiết lập một = đến b trong đó a = = b (tức là nó sẽ không làm gì cả). – Hermit

+0

Lỗi không thành công trên phần của tôi :) – Woot4Moo

0

Hãy thử ..
CẬP NHẬT SẢN XUẤT một
SET (tên, đếm) = (
tên SELECT, đếm
TỪ dàn b
ĐÂU a.ID = b.ID)
nơi có (SELECT 1
TỪ dàn b
WHERE a.ID = b.ID
);

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