我可以在 PL/SQL 块中使用 REGEXP_LIKE 作为 IF 的条件吗
Posted
技术标签:
【中文标题】我可以在 PL/SQL 块中使用 REGEXP_LIKE 作为 IF 的条件吗【英文标题】:Can i use REGEXP_LIKE as a condition with IF in a PL/SQL block 【发布时间】:2016-11-11 11:59:42 【问题描述】:我正在尝试创建一个函数,旨在遍历组织单元树,根据它们在树结构中的级别和它们出现在我们的 Intranet 页面上的天气过滤掉一些组织单元。该函数的输入是起始单元的 ORG_UNIT_ID,一个显示我们是否应该关心 Intranet 标志的标志和一个逗号分隔的级别列表。例如“2,3”。我正在尝试将 REGEXP_LIKE 与循环内的 ELSEIF 结合使用以向上运行树,直到遇到第一个符合条件的父单元。
T_STOP 是循环的控制变量。 R_ORG_UNIT_OVER 用于查询上述单元的元数据。在循环第一次传递期间,这将是作为输入传递给函数的单元之上的单元。
光标定义:
CURSOR C_ORG_UNIT_OVER(V_ORG_UNIT_ID ORG_UNIT.ORG_UNIT_ID%TYPE) IS
SELECT ORUI.ORG_UNIT_ID
, ORUI.ORG_LEVEL
, ORUI.SHOW_ON_INTRANET
FROM ORG_UNIT ORUI
JOIN ORG_UNIT_PARENT OUPA ON ORUI.ORG_UNIT_ID=OUPA.ORG_UNIT_ID_PARENT
WHERE OUPA.ORG_UNIT_ID = V_ORG_UNIT_ID;
循环中失败的代码段:
IF R_ORG_UNIT_OVER.SHOW_ON_INTRANET = 'N' THEN
T_ORG_UNIT_ID := R_ORG_UNIT_OVER.ORG_UNIT_ID;
ELSEIF REGEXP_LIKE (P_SKIP_LEVEL, '(^|,)' || R_ORG_UNIT_OVER.ORG_LEVEL || '($|,)') THEN
T_ORG_UNIT_ID := R_ORG_UNIT_OVER.ORG_UNIT_ID;
ELSE
T_STOP := 'Y';
END IF;
但是,此代码总是在 REGEXP_LIKE 符号上引发 PLS-00103 错误。当 REGEXP_LIKE 用作 PL/SQL IF/ELSEIF 块中的条件而不是常规查询时,是否存在某种限制或替代方式?
【问题讨论】:
这看起来有效。您得到的完整错误堆栈是什么,其中的行号与您显示的内容有何关系?您是否调试过R_ORG_UNIT_OVER.ORG_LEVEL
出错时的实际值?您使用的是哪个版本的 Oracle?一些上下文也可能有用 - 实际问题可能在前面。
我尝试将 REGEXP_LIKE 替换为更基本的 = 检查游标变量。它工作得很好,但每当我用 REGEXP_LIKE 替换它时,我都会得到显示的错误。我可以附上完整的错误日志,但鉴于这是来自更大用例的一个小例子,它可能没有多大意义。
好的,但这适用于最近的版本;可能在 9i 中没有(不记得当它被添加到 PL/SQL 时),所以你使用的是旧版本吗?
所以我可能把她搞砸了。我将修改 IF 语句以更准确地反映我的代码。每个部分都单独工作,但作为 IF-ELSEIF-ELSE 语句的一部分,它会失败。
是的,如果您显示实际产生错误的代码 *8-)
【参考方案1】:
PL/SQL uses ELSIF
, not ELSEIF
。通过您的编辑,您的代码确实会出现您描述的错误;有了这个它不会:
IF R_ORG_UNIT_OVER.SHOW_ON_INTRANET = 'N' THEN
T_ORG_UNIT_ID := R_ORG_UNIT_OVER.ORG_UNIT_ID;
ELSIF REGEXP_LIKE (P_SKIP_LEVEL, '(^|,)' || R_ORG_UNIT_OVER.ORG_LEVEL || '($|,)') THEN
T_ORG_UNIT_ID := R_ORG_UNIT_OVER.ORG_UNIT_ID;
ELSE
T_STOP := 'Y';
END IF;
【讨论】:
谢谢。我整天盯着这个docs.oracle.com/cloud/latest/db112/LNPLS/…,还是没注意到:(【参考方案2】:是的,你可以。
declare
testvar varchar2(20) := 'Kittens';
begin
if regexp_like(testvar, '^K') then
dbms_output.put_line(testvar || ' matches ''^K''');
end if;
end;
Kittens matches '^K'
PL/SQL procedure successfully completed.
包括一些测试数据,我会尝试看看有什么没有按预期工作。例如,
declare
p_skip_level number := 2;
org_level number := 3;
begin
if regexp_like (p_skip_level, '(^|,)' || org_level || '($|,)')
then
dbms_output.put_line('Matched');
else
dbms_output.put_line('Not matched');
end if;
end;
【讨论】:
以上是关于我可以在 PL/SQL 块中使用 REGEXP_LIKE 作为 IF 的条件吗的主要内容,如果未能解决你的问题,请参考以下文章
是否可以在 PL/SQL 开发人员测试窗口的“声明”块中声明子过程?
您可以将 CREATE TABLE 语句放在 PL/SQL 块中吗?