2013-04-12 34 views
5

Tôi có một truy vấn SQL với cùng mã chính xác, nhưng hai bảng khác nhau (AUDIT_TRAIL_ARCHIVE và AUDIT_TRAIL). Tôi sử dụng "UNION ALL" để có một kết quả.Không lặp lại chính mình: cùng một truy vấn SQL, nhưng hai bảng khác nhau

Người lập trình giỏi sử dụng nguyên tắc "Don't repeat yourself". Người lập trình giỏi tránh WET (viết mọi thứ hai lần).

Làm cách nào để viết lại mã này bằng nguyên tắc "Không lặp lại chính mình"?

SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
FROM AUDIT_TRAIL_ARCHIVE AU 
    INNER JOIN 
     (SELECT RSS_USER_NAME 
     FROM RSS_USER 
     WHERE RSS_NAME = 'rmad' 
       AND ADD_INFO_MASTER LIKE '%__47__UPN=%@richemont.com%') FALSCH 
    ON REPLACE (AU.ENTITY_KEY, 'rss_user_name=CN=', '') = 
     FALSCH.RSS_USER_NAME 
WHERE  AU.RSS_NAME = 'rmad' 
    AND AU.TABLE_NAME = 'rss_user' 
    AND AU.ACTION = 'Insert' 
    AND AU.ENTITY_KEY LIKE 'rss_user_name=CN=%' 
    AND AU.ORIGIN != 'RSS' 
UNION ALL 
SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
FROM AUDIT_TRAIL AU 
    INNER JOIN 
     (SELECT RSS_USER_NAME 
     FROM RSS_USER 
     WHERE RSS_NAME = 'rmad' 
       AND ADD_INFO_MASTER LIKE '%__47__UPN=%@richemont.com%') FALSCH 
    ON REPLACE (AU.ENTITY_KEY, 'rss_user_name=CN=', '') = 
     FALSCH.RSS_USER_NAME 
WHERE  AU.RSS_NAME = 'rmad' 
    AND AU.TABLE_NAME = 'rss_user' 
    AND AU.ACTION = 'Insert' 
    AND AU.ENTITY_KEY LIKE 'rss_user_name=CN=%' 
    AND AU.ORIGIN != 'RSS' 
+0

Mục tiêu của bạn ở đây là gì: để sử dụng sql động, ví dụ: cùng sql nhưng khác. bảng hoặc viết lại truy vấn như trong ví dụ của Florin? – Art

+0

@ fyodor78 Giải pháp đầu tiên không phải lúc nào cũng tốt nhất. Tất nhiên bạn có thể tham gia các bảng TRƯỚC KHI chọn - nhưng tại sao bạn sẽ xây dựng một bảng tạm thời 100.000 hàng, khi bạn muốn lấy một hàng từ mỗi hàng? Xem tại SQL động, tạo một thủ tục, xây dựng một chuỗi truy vấn và sử dụng lại thủ tục đó. – dognose

Trả lời

4

Ví dụ:

SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
FROM (select * --or relevant columns 
      from AUDIT_TRAIL_ARCHIVE AU 
      union all 
      select * 
      from AUDIT_TRAIL AU 
      ) AU 
    INNER JOIN 
     (SELECT RSS_USER_NAME 
     FROM RSS_USER 
     WHERE RSS_NAME = 'rmad' 
       AND ADD_INFO_MASTER LIKE '%__47__UPN=%@richemont.com%') FALSCH 
    ON REPLACE (AU.ENTITY_KEY, 'rss_user_name=CN=', '') = 
     FALSCH.RSS_USER_NAME 
WHERE  AU.RSS_NAME = 'rmad' 
    AND AU.TABLE_NAME = 'rss_user' 
    AND AU.ACTION = 'Insert' 
    AND AU.ENTITY_KEY LIKE 'rss_user_name=CN=%' 
    AND AU.ORIGIN != 'RSS' 
+0

Tôi có nghĩ rằng bạn sẽ không thể lọc hai lựa chọn mà bạn 'UNION ALL' bằng các giá trị từ phần còn lại của truy vấn? – Lilienthal

+1

No. Thực ra, câu trả lời lọc hai truy vấn trong mệnh đề where: 'AU.TABLE_NAME = 'rss_user''. AU là bí danh cho toàn bộ công đoàn. Bộ lọc có thể được động cơ đẩy để lọc trước khi thực hiện phép nối. –

0

lập trình viên giỏi sử dụng "Đừng lặp lại chính mình" nguyên tắc. Người lập trình giỏi tránh WET (viết mọi thứ hai lần).

Heh. Tôi thích nó. tế nhị.

cũng có, tôi có lẽ sẽ là quá cơ bản nhưng một cái gì đó giống như công việc này:

CREATE [OR REPLACE] PROCEDURE <name_of_procedure> [ (<ENTITY_KEY_variable>) ] 
IS 
    <ENTITY_KEY=ENTITY_KEY_variable> 
BEGIN 
    <your code goes here> 

    [EXCEPTION 
     exception_section] 
END [procedure_name]; 

chỉnh sửa: tôi thấy từ câu trả lời đăng tải đầu tiên tôi đã cho một trolling? tôi ngớ ngẩn quá.

+0

@@ Bryan Devaney: Mã của bạn sẽ không bao giờ hoạt động trong Oracle. Vui lòng sửa lại. – Art

+0

xin lỗi, xuất hiện dưới sql, nghĩ rằng đó là mysql ... cập nhật câu trả lời ngay bây giờ –

0

Đơn giản là bạn không thể. SQL được biên dịch ngôn ngữ (ngay cả khi nó trông giống như kịch bản) và Oracle nhớ OBJECT_ID truy vấn phụ thuộc. Mỗi nửa truy vấn có các phụ thuộc khác nhau, khác nhau "bytecode" và kế hoạch thực hiện khác nhau.

Bạn có thể

  • Sử dụng bảng phân vùng. Sau đó, bạn sẽ chỉ có một bảng. Các truy vấn đối với dữ liệu trực tiếp có thể bị hạn chế bằng cách sử dụng "select * from ACTIT_TRAIL partition ACTIVE".

  • Sử dụng truy vấn bao thanh toán như

    WITH AU AS 
    (SELECT * from AUDIT_TRAIL union all select * from AUDIT_TRAIL_ARCHIVE) 
    SELECT REPLACE (ENTITY_KEY, 'rss_user_name=CN=', '') 
    FROM AU JOIN ... 
    ... 
    

    Nhưng tôi không chắc chắn cho dù trong trường hợp này Oracle sẽ đảm bảo hiệu quả cùng của kế hoạch thực hiện.