2011-03-21 35 views
35

Tôi có một tập lệnh sử dụng một chồng với mệnh đề để đưa ra một số kết quả, và sau đó tôi muốn viết kết quả đó trong một bảng. Tôi chỉ không thể có được đầu của tôi xung quanh nó, ai đó có thể chỉ cho tôi đi đúng hướng?Tuyên bố cập nhật sử dụng với điều khoản

Dưới đây là một ví dụ đơn giản cho biết những gì tôi muốn làm:

with comp as (
    select *, 42 as ComputedValue from mytable where id = 1 
) 
update t 
set  SomeColumn = c.ComputedValue 
from mytable t 
     inner join comp c on t.id = c.id 

Điều thực có khá nhiều với điều khoản rằng tất cả các tài liệu tham khảo lẫn nhau, vì vậy bất kỳ lời đề nghị thực sự sử dụng quy định tại khoản sẽ được ưa thích đánh giá cao thay đổi cấu trúc lại thành các truy vấn con lồng nhau.

Cảm ơn trước,

Gert-Jan

+2

FYI: Bạn không cần phải chỉnh sửa tiêu đề và câu hỏi của bạn để chỉ ra rằng bạn đã trả lời nó cho mình. Chỉ cần thêm giải pháp của bạn làm câu trả lời của riêng mình và chọn giải pháp đó nếu câu trả lời hay nhất. –

+0

Ok đã làm điều đó, không thể đánh dấu nó là đã trả lời. Cảm ơn! – gjvdkamp

+0

tôi cũng đang tìm kiếm phản hồi và tôi đã tìm thấy câu trả lời ở đây: http://stackoverflow.com/questions/7030699/oracle-sql-update-with-data-from-another-table – Bogdan

Trả lời

36

Nếu có ai đến đây sau tôi, đây là câu trả lời phù hợp với tôi.

update mytable t 
set z = (
    with comp as (
    select b.*, 42 as computed 
    from mytable t 
    where bs_id = 1 
) 
    select c.computed 
    from comp c 
    where c.id = t.id 
) 

Chúc may mắn,

GJ

+3

Sẽ không cập nhật tất cả các hàng này? Nếu có các hàng có c.id <> t.id, chúng sẽ không được đặt thành null không? Có ai biết một cách để đặt rằng nơi khoản bên ngoài quá? –

+0

Không sử dụng Oracle nữa và điều này đã trở lại. Hãy thử nó và cho chúng tôi biết ;-) IIRC này làm việc cho tôi. – gjvdkamp

+0

@gjvdkamp nó hoạt động giống như Sanjay Nambiar cho biết: bản cập nhật hoạt động trên các hàng đã chọn, nhưng tất cả các hàng khác nằm ngoài "vị trí" được đặt thành rỗng. [2] Có ai biết cách đặt mệnh đề đó ở bên ngoài không? – robsonrosa

24

WITH cú pháp dường như là hợp lệ trong một cái nhìn nội tuyến, ví dụ

UPDATE (WITH comp AS ... 
     SELECT SomeColumn, ComputedValue FROM t INNER JOIN comp ...) 
    SET SomeColumn=ComputedValue; 

Nhưng trong các bài kiểm tra nhanh chóng tôi đã này luôn thất bại với ORA-01732: data manipulation operation not legal on this view, mặc dù nó đã thành công nếu tôi viết lại để loại bỏ các mệnh đề WITH. Vì vậy, việc tái cấu trúc có thể can thiệp vào khả năng của Oracle để đảm bảo bảo toàn khóa.

Bạn sẽ có thể sử dụng MERGE. Sử dụng ví dụ đơn giản mà bạn đã đăng này thậm chí không yêu cầu mệnh đề WITH:

MERGE INTO mytable t 
USING (select *, 42 as ComputedValue from mytable where id = 1) comp 
ON (t.id = comp.id) 
WHEN MATCHED THEN UPDATE SET SomeColumn=ComputedValue; 

Nhưng tôi hiểu bạn có một truy vấn con phức tạp hơn mà bạn muốn tính toán. Tôi nghĩ rằng bạn sẽ có thể tạo truy vấn con trong mệnh đề USING tùy ý phức tạp, kết hợp nhiều mệnh đề WITH.

+1

Xin chào, cảm ơn rất nhiều vì nỗ lực của bạn, đã quản lý để chạy nó. Các câu lệnh mà tôi sử dụng có khá nhiều mức tính toán trung bình và stddev, sau đó sử dụng dữ liệu không bình thường (thống kê) từ các tabels khác, vv sẽ là một nỗi đau thực sự để tái cấu trúc. Ví dụ này chỉ là cú pháp cập nhật. – gjvdkamp

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