【问题标题】:Inline table in Oracle SQLOracle SQL 中的内联表
【发布时间】:2011-03-31 21:37:51
【问题描述】:

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

我可以给这个软件 SQL 查询,比如“select username, firstname, lastname from users where username in ?”

软件比填?与 ('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 中可能的每个值(即无限大)。

我试过 select 吗?来自双重,但不幸的是,这只在什么时候有效?类似于 ('x'),而不是 ('x', 'y')。

请记住,我无法更改 ?出来了,所以我做不了select 'alice' from dual union all select 'bob' from dual

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

【问题讨论】:

  • 对我来说不清楚,所以你试图通过创建一个带有虚假用户名的虚拟表来防止数据库返回 NO 行,因为用户不存在?也许我理解错了,但目标是什么?

标签: sql oracle


【解决方案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 作为绑定变量完成,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

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

【讨论】:

    【解决方案2】:

    你可以使用流水线函数:

    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 函数以遍历集合并管道化集合中的每个项目。

    【讨论】:

      猜你喜欢
      • 2016-10-21
      • 2014-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      • 2018-08-27
      相关资源
      最近更新 更多