Oracle SQL中的内联表

时间:2011-03-31 09:01:52

标签: sql oracle

我正在尝试集成一些查询我可以修改的数据库的软件(我无法修改)。

我可以给这个软件提供SQL查询,例如“从用户名中选择用户名,名字,姓氏吗?”

软件比填写?用'alice','bob')之类的东西,并获取用户信息。

事情是,还有另一个软件,我再次无法修改,偶尔会生成像'user2343290'这样的用户,并将它们提供给第一个软件。当然,它会抛出错误,因为它无法找到该用户。

所以我想要运行的查询是这样的:

select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from create_table(?) t

其中create_table生成一个表,其中包含?中提到的行,第一列名为column1。

或者:

select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from _universe_ t where t.column1 in ?

其中_universe_是一个伪表,其中包含column1中的每个值(即无限大)。

我试过选择?来自双重,但不幸的是这只能在什么时候起作用?就像('x'),而不是('x','y')。

请记住我无法改变格式如何?出来了,所以我做不到select 'alice' from dual union all select 'bob' from dual

任何人都知道我怎么能做我所提到的,或其他类似的效果?

2 个答案:

答案 0 :(得分:1)

您可以将分隔的名称字符串转换为表格类型,如下所示:

CREATE TYPE name_tab AS TABLE OF VARCHAR2(30);
/

SELECT * FROM table(name_tab('alice','bob'));

所以你只需要创建类型然后你的例子就会变成:

select username, firstname, lastname from users where username in ?
UNION ALL
select t.column1, 'Unknown', 'Unknown' from table(name_tab ?) t

(我假设?被简单的文本替换取代 - 因为如果它作为绑定变量完成而IN不起作用 - 并且替换文本包括括号。)

但是,我不确定这个结果是否有用,因为当给出一个好的用户名列表时,你现在每个用户名都有两个结果行,一个包含实际信息,另一个包含“未知” '价值观。

更好地查询查询的方法可能是:

select t.column_value username,
       NVL(users.firstname,'Unknown'),
       NVL(users.lastname,'Unknown')
  from table(name_tab ?) t left join users on users.username = t.column_value

这应该为每个用户名提供一行,如果存在,则为实际数据;如果不存在,则为“未知”值。

答案 1 :(得分:0)

您可以使用流水线功能:

create type empname_t is table of varchar2(100);

create or replace function to_list(p_Names in string) return empname_t pipelined is
begin
  pipe row(p_Names);
  return;
end;

select * from table(to_list('bob'))

如果您需要拆分名称(例如'bob,alice'),您可以使用接受字符串并返回empname_t的函数,例如: Tom Kyte的in_list,见
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:210612357425
并修改to_list函数以迭代集合并管道集合中的每个项目。