有没有一种有效的方法来避免SQL中的固定值UNION?
问题描述:
例如与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特有的?
谢谢
答
贝努瓦,
你可以有一列用这个表:
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。
答
好吧,我同意
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
答
有几种方法可以做到这一点(如上面已经指出,这里有一些更多)
所有这些都是从asktom问题: http://tkyte.blogspot.com/2006/06/varying-in-lists.html 和 http://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
你可以把它们当成表格
如何使用表格存储* fixed *值? – dotjoe 2011-03-24 13:50:37
@dotjoe:你如何快速填充它? 'INSERT INTO SELECT UNION SELECT'表。 – Benoit 2011-03-24 13:51:56
难道你不能简单地填写一次,重用表?或者值改变了吗? – dotjoe 2011-03-24 14:02:34