PLSQL forall 中遇到符号“IF”

Posted

技术标签:

【中文标题】PLSQL forall 中遇到符号“IF”【英文标题】:PLSQL Encountered the symbol "IF" in forall 【发布时间】:2021-03-24 08:59:44 【问题描述】:

当尝试得到错误时,是否可以在 forall 中使用 if 语句 PLS-00103:在预期以下情况之一时遇到符号“IF”:。 ( * @ % & - + / at mod 余数 rem 选择更新与

 FORALL i IN 1 .. P_DAYS_IDS.COUNT
         if (P_DAYS_IDS(i) = 1) then
            Update test set col_1 = 'Y' where id = 1;
         elsif (P_DAYS_IDS(i) = 2) then
            Update test set col_2 = 'Y' where id = 2;
         end if;

【问题讨论】:

【参考方案1】:

没有。 forall 的存在是为了消除 SQL 和 PL/SQL 之间的上下文转换,因此它仅在您使用集合的每个元素执行单个 SQL 操作时才有效。

如果您想在循环中执行 PL/SQL 代码,可以使用常规的 for 循环。

FOR i IN 1 .. P_DAYS_IDS.COUNT
LOOP
     if (P_DAYS_IDS(i) = 1) then
        Update test set col_1 = 'Y' where id = 1;
     elsif (P_DAYS_IDS(i) = 2) then
        Update test set col_2 = 'Y' where id = 2;
     end if;
end loop;

【讨论】:

【参考方案2】:

您不能在 FORALL 中使用 IF,因为它恰好需要 1 个 DML,并且 SQL 中没有 IF。但是,测试的条件迁移到 CASE 表达式或 WHERE 子句。为此,您可以将 IF 谓词和 WHERE 子句组合成一个 CASE 表达式,用于可能更新的每一列。

forall i in 1 .. p_days_ids.count         
    update test 
       set col_1 =  case when p_days_ids(i) = 1 and id = 1 then 'Y' else col_1 end   
         , col_2 =  case when p_days_ids(i) = 2 and id = 2 then 'Y' else col_2 end; 

注意,当列在 SET 中被引用时,需要分配一个值。因此,如果不满足 when 条件,则将列设置为其当前值。

【讨论】:

以上是关于PLSQL forall 中遇到符号“IF”的主要内容,如果未能解决你的问题,请参考以下文章

PLSQL 在期望以下之一时遇到符号“YES”

如何修复“在预期以下情况之一时遇到符号“=”:plsql中的错误

PL SQL 遇到符号“文件结尾”... PLS-00103

错误:00103 用于 plsql 过程

我应该清除每个要在 forall 中使用的 fetch 循环的集合吗? PLSQL 甲骨文

FORALL和BULK COLLECT