【问题标题】:oracle function syntax errororacle函数语法错误
【发布时间】:2018-08-21 21:06:44
【问题描述】:

我有以下 oracle 函数,它有 num_list 作为逗号分隔列表的输入,然后检查此列表中的数字是否存在于某个表中:

create or replace FUNCTION get_num_exist (num_list varchar2,separator varchar2) 
    RETURN nbs PIPELINED 
as
    row_type nb;
begin

    with numbers as 
    (select regexp_substr(num_list,'[^'||separator||']+', 1, level)num_  
     from dual
     connect by regexp_substr(num_list, '[^'||separator||']+', 1, level) is not null)


    for r_row in (select * from numbers
                  where num_  in (select phone_number 
                                   from phone_numbers) )
    loop
        PIPE ROW(nb(r_row.num_));
    end loop;
    return;

end;

但它在 for 循环级别给出了语法错误。

任何帮助将不胜感激。

【问题讨论】:

  • 您已经使用 for 循环拆分了 CTE 和 CTE 中的选择,这是行不通的。 with 子句必须与 select 一起使用 - 尽管此函数的真正目的尚不清楚。如果您能提供更多关于您想要实现的目标的详细信息,这可能会有所帮助,
  • 你的 with 子句大概属于游标吧?如果是这样,它应该是循环光标的一部分,即for r_row in (with numbers as (...) select * from numbers ...
  • @Andrew 我想从 phone_numbers 表中的列表中返回号码。

标签: oracle function plsql


【解决方案1】:

您似乎在混合使用 SQL 和 PL/SQL。

for r_row in (
    with numbers as 
      (select regexp_substr(num_list,'[^'||separator||']+', 1, level) num_
         from dual
       connect by regexp_substr(num_list, '[^'||separator||']+', 1, level)
         is not null )
    select * from numbers where num_ in (
       select phone_number from phone_numbers) )
loop
    PIPE ROW(nb(r_row.num_));
end loop;

但我以前用另一种方式来做(我认为更快,但如果 phone_numbers.phone_number 上有索引,就不会这样了)。

for r_row in (
  select phone_number num_ from phone_numbers
    where instr(separator || num_list || separator,
                separator || phone_number || separator) > 0
) loop
    PIPE ROW(nb(r_row.num_));
end loop;

也许是一个解释。我将分隔符放在搜索列表之前和之后,以及数据库列之前和之后(以避免误报)。使用 instr > 0,我模拟 Oracle(或任何 DB)“其中 phone_number IN (..., ..., ...)”。

【讨论】:

  • 感谢您的建议。你的意思是如果phone_number字段上有索引,你的方法会很慢,然后经典的“where num in (select,,,)”会更快?
  • 是的,我的构造不允许使用索引。当您想避免使用索引(因为它没有选择性)或没有不能使用的索引时,请使用它。在您的情况下,phone_number 可能是 phone_numbers 的 PK,您的构建将快一千倍。使用分层查询拆分列表的巧妙技巧。你在 Tom Kyte 上找到了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-22
  • 2014-11-26
  • 2015-09-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
相关资源
最近更新 更多