简体   繁体   English

Oracle SQL中的内联表

[英]Inline table in Oracle SQL

I'm trying to integrate with some software (that I can't modify) that queries a database that I can modify. 我正在尝试与一些我可以修改的数据库进行查询的软件(无法修改)集成。

I can give this software SQL queries, like so "select username, firstname, lastname from users where username in ?" 我可以给该软件执行SQL查询,例如“从用户名在哪里的用户中选择用户名,名字,姓氏”。

The software than fills in the ? 该软件比? with something like ('alice', 'bob'), and gets user information for them. 与类似(“ alice”,“ bob”)之类的内容,并获取它们的用户信息。

Thing is, there's another piece of software, which I again can't modify, which occasionally generates users like 'user2343290' and feeds them through to the first piece of software. 问题是,还有另一个软件,我再次无法修改,该软件偶尔会生成“ user2343290”之类的用户,并将其提供给第一个软件。 Of course, it throws errors because it can't find that user. 当然,它会因为找不到该用户而引发错误。

So the query I want to run is something like this: 所以我想运行的查询是这样的:

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

where create_table generates a table with the rows mentioned in ?, with the first column named column1. 其中create_table生成一个表,其中包含?中提到的行,第一列名为column1。

Or alternatively: 或者:

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

where _universe_ is some fake table that contains possible every value in column1 (ie infinitely large). 其中_universe_是一些伪造的表,其中可能包含column1中的每个值(即,无限大)。

I've tried select ? 我尝试选择? from dual, but unfortunately this only worked when ? 从双重开始,但不幸的是,这仅在什么时候起作用? was something like ('x'), not ('x', 'y'). 类似于('x'),而不是('x','y')。

Keep in mind I can't change the format of how the ? 请记住,我无法更改格式? comes out, so I can't do select 'alice' from dual union all select 'bob' from dual . 出来,所以我不能select 'alice' from dual union all select 'bob' from dual

Anyone know how I could do what I've mentioned, or something else to have a similar effect? 有谁知道我该怎么做,或者有其他类似的效果?

You can turn the delimited string of names into a table type like so: 您可以将定界的名称字符串转换为表类型,如下所示:

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

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

So you would just need to create the type then your example would become: 因此,您只需要创建类型,然后您的示例将变为:

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

(I'm assuming that the ? is replaced by simple text substitution -- because the IN wouldn't work if it was done as a bind variable -- and that the substituted text includes the parentheses.) (我假设将?替换为简单的文本替换-因为如果将IN作为绑定变量完成,则IN无效-并且替换后的文本包含括号。)

However, I am not sure the result of this will be helpful, since when a list of good usernames is given, you'll now have two result rows for each username, one with the actual information and another with the 'Unknown' values. 但是,我不确定这样做的结果是否会有所帮助,因为当给出一个好的用户名列表时,每个用户名现在将有两个结果行,一个具有实际信息,而另一个具有“未知”值。

A better way to phrase the query might be: 用短语表达查询的更好方法可能是:

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

That should give you one row per username, with the actual data if it exists, or the 'Unknown' values if it does not. 那应该给您每个用户名一行,如果存在则包含实际数据,如果不存在则显示“未知”值。

You could use a pipelined function: 您可以使用管道函数:

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'))

If you need to split the names (eg 'bob,alice'), you could use a function accepting a string and returning a empname_t, eg Tom Kyte's in_list, see 如果需要分割名称(例如'bob,alice'),则可以使用接受字符串并返回empname_t的函数,例如Tom Kyte的in_list,请参见
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:210612357425 http://asktom.oracle.com/pls/apex/f?p=100:11:0:::::P11_QUESTION_ID:210612357425
and modify the to_list function to iterate over the collection and pipe each item from the collection. 并修改to_list函数以遍历集合并通过管道传递集合中的每个项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM