2011-03-24 79 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 

你可以把它们当成表格

相关问题