2011-03-24 78 views
3

例如與Oracle:我想要一些臨時表是用於合併:有沒有一種有效的方法來避免SQL中的固定值UNION?

MERGE INTO my_target_table 
USING (
     WITH tbl1 AS (  SELECT 'a' col1 FROM dual   -- <--- THIS 
         UNION SELECT 'foo' col1 FROM dual   -- <--- IS 
         UNION SELECT 'doh' col1 FROM dual   -- <--- CRAPPY 
        ), 
      tbl2 AS (  SELECT 'b' col2, 'c' col3 FROM dual -- <--- THIS 
         UNION SELECT 'x' col2, 's' col3 FROM dual -- <--- ALSO 
        ) 
     SELECT col1, col2, col3 FROM tbl1 CROSS JOIN tbl2 
    ) my_source_view 
    ON ( my_target_table.col1 = my_source_view.col1 
     AND my_target_table.col2 = my_source_view.col2 
    ) 
WHEN MATCHED THEN UPDATE 
         SET my_target_table.col3 = my_source_view.col3 
WHEN NOT MATCHED THEN INSERT(    col1,    col2,    col3) 
         VALUES(my_source_view.col1, my_source_view.col2, my_source_view.col3) 
; 

這裏的SELECT UNION SELECT模式實在是煩人,我覺得它可怕(重複,冗長)。

難道你有一個技巧來僞造類似的查詢,不管它是否是Oracle特有的?

謝謝

+1

如何使用表格存儲* fixed *值? – dotjoe 2011-03-24 13:50:37

+1

@dotjoe:你如何快速填充它? 'INSERT INTO SELECT UNION SELECT'表。 – Benoit 2011-03-24 13:51:56

+0

難道你不能簡單地填寫一次,重用表?或者值改變了嗎? – dotjoe 2011-03-24 14:02:34

回答

6

貝努瓦,

你可以有一列用這個表:

SQL> with tbl1 as 
    2 (select column_value col1 
    3  from table(sys.dbms_debug_vc2coll('a','foo','doh')) 
    4 ) 
    5 select * 
    6 from tbl1 
    7/

COL1 
------------------------------------------------------------ 
a 
foo 
doh 

3 rows selected. 

超過一列你需要創建兩種類型(或使用現有的),如下所示:

SQL> create type ot is object 
    2 (col1 varchar2(1) 
    3 , col2 varchar2(1) 
    4 ); 
    5/

Type created. 

SQL> create type ntt is table of ot; 
    2/

Type created. 

SQL> with tbl2 as 
    2 (select * 
    3  from table(ntt(ot('b','c'),ot('x','s'))) 
    4 ) 
    5 select * 
    6 from tbl2 
    7/

C C 
- - 
b c 
x s 

2 rows selected. 

Regards,
Rob。

+0

謝謝。我喜歡這個答案的第一部分(對於一個col表)。也許另一個軟件包可以以更通用的方式做到這一點? – Benoit 2011-03-24 14:08:06

+0

它不是一個包,而是一個集合(嵌套表類型)。在SYS模式中有幾個可以使用的預定義的模式。另一個答案中的「odcivarchar2List」也是可以使用的。如果你喜歡,你當然可以自己創建一個。 – 2011-03-24 14:18:31

+0

+1:很好地完成 – DCookie 2011-03-24 15:05:44

1

好吧,我同意

SELECT 'a' col1 FROM dual 
    UNION SELECT 'foo' col1 FROM dual 
    UNION SELECT 'doh' col1 FROM dual 

是糟糕的。您是否同意

SELECT 'a' col1 FROM dual 
    UNION ALL SELECT 'foo' col1 FROM dual 
    UNION ALL SELECT 'doh' col1 FROM dual 

是不是?

編輯

如果你不喜歡的語法的某些部分,你可以嘗試動態SQL(但一定要明白,這是你的個人喜好,所以嘗試從做它更大的制度來約束) 。

這裏有一個鏈接http://www.oracle-base.com/articles/misc/DynamicInLists.php

+0

它更少,但對於我的示例來說,它是無用的優化它(你甚至失去更多的時間鍵入UNION ALL!)。我想要的是例如一些內置的方式來將列表轉換爲臨時表。 – Benoit 2011-03-24 13:54:34

+0

基本上你不喜歡語法,因爲它太冗長了?如果是這樣,你可以請更新你的問題。我會更新我的答案...... – Unreason 2011-03-24 14:06:47

+1

@非理性:你說得對,這就是我的感受。太冗長了,所以我覺得必須有更好的辦法。 – Benoit 2011-03-24 14:10:16

3

在SQL Server 2008中您可以使用VALUES條款。不確定這是否在Oracle中可用,但是您確實需要所有技術。

示例語法

SELECT col1 FROM (VALUES ('a'),('foo'), ('doh')) T (col1) 
+0

這是件好事。不幸的是,Oracle不會允許它看起來像。 – Benoit 2011-03-24 14:04:22

+0

+1給我展示新東西 – dotjoe 2011-03-24 14:04:25

2

有幾種方法可以做到這一點(如上面已經指出,這裏有一些更多)

所有這些都是從asktom問題: http://tkyte.blogspot.com/2006/06/varying-in-lists.htmlhttp://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:210612357425

var mystring varchar2 
begin 
:mystring := trim('a,foo,doh,b,x'); 
end; 
/


SELECT 

    substr(v.mystring, v.start_of_string, v.next_comma_location - v.start_of_string) "The String" 
     FROM (SELECT comma_location + 1 start_of_string, 
        mystring, 
        nvl(lead(comma_location, 1) over(ORDER BY comma_location), mystring_length + 1) AS 
    next_comma_location 
       FROM (SELECT :mystring mystring, 
          instr(:mystring, ',', LEVEL) comma_location, 
          length(:mystring) mystring_length 
         FROM dual 
        CONNECT BY LEVEL < length(:mystring))) v 
    WHERE v.start_of_string < v.next_comma_location; 

- - 或者 http://laurentschneider.com/wordpress/2007/12/predefined-collections.html

select * from table(sys.odcivarchar2List('a','foo','doh','b','x')); 




COLUMN_VALUE                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
---------------- 
a                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
foo                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
doh                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
b                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
x 

你可以把它們當成表格

相關問題