【问题标题】:FOR LOOP with WHERE clause带有 WHERE 子句的 FOR LOOP
【发布时间】:2019-09-13 23:36:08
【问题描述】:

这个问题之前已经提出过,但不是专门针对 Oracle 数据库提出的。

可以使用 WHERE 子句过滤 FOR LOOP 吗?例如,我想做类似的事情:

--LOG ERRORS
FOR err in c_errors WHERE trx_type='CYCLE_COUNT'
LOOP

    ...do some stuff

END LOOP; 

此代码给出错误:

PLS-00103: Encountered the symbol "WHERE" when expecting one of the following ...

这有合适的语法吗?

这里是游标定义。它抓取周期计数和调整交易类型。但是在上面提到的日志错误部分,我只想报告循环计数错误。当然我可以使用单独的游标,但我试图用一个来完成。

    CURSOR c_errors IS
        SELECT DISTINCT CC_ENTRY_INTERFACE_ID INTERFACE_ID
            ,ERROR_MESSAGE
            ,creation_date
            ,LAST_UPDATE_DATE
            ,'CYCLE_COUNT' TRX_TYPE
        FROM mtl_cc_interface_errors
        UNION
        SELECT DISTINCT TRANSACTION_INTERFACE_ID
            ,ERROR_EXPLANATION
            ,CREATION_DATE
            ,LAST_UPDATE_DATE
            ,'ADJUSTMENT'
        FROM mtl_transactions_interface 
        WHERE process_flag=3 
            AND error_code IS NOT NULL
        ORDER BY last_update_date DESC;

【问题讨论】:

  • 为了什么?请描述您正在尝试做的事情。样本数据和所需结果的帮助。
  • 我想我可以在进入循环后使用 IF ,但它并没有真正达到预期的结果,因为它仍然会循环遍历光标选择的所有记录。也许需要一个单独的光标。

标签: oracle plsql


【解决方案1】:

FOR err in c_errors WHERE trx_type='CYCLE_COUNT'

这在语义上是不正确的。

作为选项之一,您可以做的是创建参数化游标。 这里是an example

案例#1:参数为空。返回所有行

set serveroutput on;
declare
  cursor l_cursor ( param1 varchar2) is
    select *
      from (
            select level  as c1
                 , 'cycle_count' as trx_type
              from dual
            connect by level < 3
            union all
            select level  as c1
                 , 'adjustemnt' as trc_type
              from dual
            connect by level < 3
           ) q
    where param1 is null
       or trx_type = param1;
begin
  -- param1 = null. No filter applied
  for r in l_cursor(null) loop
    dbms_output.put_line('C1: ' || to_char(r.c1) || '; ' ||
                         'TRX_TYPE: ' || r.trx_type);
  end loop;
end;

结果:

CNT: 1; TRX_TYPE: cycle_count
CNT: 2; TRX_TYPE: cycle_count
CNT: 1; TRX_TYPE: adjustemnt
CNT: 2; TRX_TYPE: adjustemnt

案例#1:按TRX_TYPE过滤

set serveroutput on;
declare
  cursor l_cursor ( param1 varchar2) is
    select *
      from (
            select level  as c1
                 , 'cycle_count' as trx_type
              from dual
            connect by level < 3
            union all
            select level  as c1
                 , 'adjustemnt' as trc_type
              from dual
            connect by level < 3
           ) q
    where param1 is null
       or trx_type = param1;
begin
  -- param1 = 'cycle_count'
  for r in l_cursor('cycle_count') loop
    dbms_output.put_line('C1: ' || to_char(r.c1) || '; ' ||
                         'TRX_TYPE: ' || r.trx_type);
  end loop;
end;

结果:

C1: 1; TRX_TYPE: cycle_count
C1: 2; TRX_TYPE: cycle_count

【讨论】:

  • 挖掘它。我会试试这个。谢谢。
  • 是的,看起来这对我有用。再次感谢。
【解决方案2】:

尼克的回答是一个很好的解释。

这是另一个如何使用它的示例,通过使用 FOR 语法声明游标内联:

BEGIN
  FOR r_product IN (
        SELECT 
            product_name, list_price 
        FROM 
            products
        WHERE list_price > 120
        ORDER BY list_price DESC
    )
  LOOP
     dbms_output.put_line( r_product.product_name ||
        ': $' || 
        r_product.list_price );
  END LOOP;
END;

来源: https://www.oracletutorial.com/plsql-tutorial/plsql-cursor-for-loop/

【讨论】:

  • 但是没有过滤光标选择的内容。它遍历整个选择列表,这是我不想做的。
  • 您可以将光标视为任何普通的选择语句。
猜你喜欢
  • 1970-01-01
  • 2011-07-23
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多