我正在尝试集成一些查询我可以修改的数据库的软件(我无法修改)。
我可以给这个软件提供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
。
任何人都知道我怎么能做我所提到的,或其他类似的效果?
答案 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函数以迭代集合并管道集合中的每个项目。