13.[SAP ABAP] RAISE 语句详解

13.[SAP ABAP] RAISE 语句详解

文章目录

在ABAP中, RAISE语句用于 触发(抛出)异常 。根据使用的是 经典异常 还是 基于类的异常RAISE的语法和用法有所不同。本章重是基于类的异常中的 RAISE EXCEPTION语句。

一、基于类异常

1. 基本语法

ABAP 复制代码
RAISE EXCEPTION TYPE <异常类名>
      [EXPORTING <参数> = <值> ... ].
  • <异常类名>:必须是继承自 CX_ROOT 的异常类(如 CX_STATIC_CHECKCX_DYNAMIC_CHECK 或自定义异常类)。
  • EXPORTING:用于传递构造异常对象所需的参数(如消息文本、错误码等)。

2. 不同类型异常的抛出

1.抛出类异常(Class-Based Exceptions)
ABAP 复制代码
" 基本用法
RAISE EXCEPTION TYPE cx_sy_zerodivide.

" 带参数
RAISE EXCEPTION TYPE cx_demo_exception
      EXPORTING
         hreadid  = cx_demo_exception => invalid_input
         previous = previous_exception_ref
         value    = '错误值'.
         
" 创建异常对象再抛出
DATA(lx_exception) = NEW cx_sy_arithmetic_error(
        hreadid   =  cx_sy_arithmetic_error => overflow
        previous  = VALUE #()
)
RAISE EXCEPTION lx_exception.
2.抛出非类异常(Legacy Exceptions)
ABAP 复制代码
" 老式异常(不推荐,仅维护旧代码使用)
RAISE division_by_zero.
" 可恢复异常
RAISE resumable_exception 
3.定义自定义异常类
ABAP 复制代码
CLASS zcx_my_exception DEFINITION
  INHERITING FROM cx_static_check
  PUBLIC
  FINAL
  CREATE PUBLIC.
  
  PUBLIC SECTION.
    INTERFACES if_t100_message. " 支持消息文本
    
    CONSTANTS:
       BEGIN OF invalid_input,
          hreadid  TYPE symsgid VALUE 'GOMSG',
          msgid    TYPE symsgid VALUE 'GOMSG',
          attr4 TYPE scx_attrname VALUE '',
       END OF invalid_input. 
       
  DATA:
      value1 TYPE string,
      value2 TYPE string.

  METHODS:
     constructor
        IMPORTING
          textid   LIKE if_t100_message=>t100key OPTIONAL
          previous LIKE previous OPTIONAL
          value1   TYPE string OPTIONAL
          value2   TYPE string OPTIONAL.
ENDCLASS.
4.定义自定义异常类
ABAP 复制代码
" 在方法中声明异常
METHODS validate_input
  IMPORTING
    input_value TYPE string
  RAISING
    zcx_my_exception.  " 声明可能抛出的异常

METHOD validate_input.
  IF input_value IS INITIAL.
    RAISE EXCEPTION TYPE zcx_my_exception
      EXPORTING
        textid = zcx_my_exception=>invalid_input
        value1 = input_value
        value2 = '不能为空'.
  ENDIF.
ENDMETHOD.
5.方法中抛出异常
ABAP 复制代码
METHOD divide_numbers
  IMPORTING
    dividend TYPE i
    divisor  TYPE i
  RETURNING
    VALUE(result) TYPE i
  RAISING
    cx_sy_zerodivide
    cx_sy_arithmetic_overflow.

  IF divisor = 0.
    RAISE EXCEPTION TYPE cx_sy_zerodivide.
  ENDIF.
  
  result = dividend / divisor.
  
  " 检查溢出
  IF result > 1000000.
    RAISE EXCEPTION TYPE cx_sy_arithmetic_overflow
      EXPORTING
        operation = 'DIVISION'
        value     = CONV string( result ).
  ENDIF.
ENDMETHOD.
6.函数模块中抛出异常
ABAP 复制代码
FUNCTION z_function_validate.
*"---------------------------------------------------------
*" 抛出异常
*"---------------------------------------------------------
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE cx_bo_error
      EXPORTING
        textid = cx_bo_error=>invalid_parameter.
  ENDIF.
ENDFUNCTION.
7. FORM 中抛出异常
ABAP 复制代码
FORM process_data
  RAISING
    cx_sy_conversion_error.

  DATA: lv_number TYPE i.
  
  TRY.
      lv_number = CONV i( 'ABC' ).
    CATCH cx_sy_conversion_error INTO DATA(lx_error).
      RAISE EXCEPTION lx_error.  " 重新抛出
  ENDTRY.
ENDFORM.
8.FORM 中抛出异常
ABAP 复制代码
FORM process_data
  RAISING
    cx_sy_conversion_error.

  DATA: lv_number TYPE i.
  
  TRY.
      lv_number = CONV i( 'ABC' ).
    CATCH cx_sy_conversion_error INTO DATA(lx_error).
      RAISE EXCEPTION lx_error.  " 重新抛出
  ENDTRY.
ENDFORM.
9.异常链(Exception Chaining)
ABAP 复制代码
METHOD process_data.
  TRY.
      " 第一步处理
      step1( ).
      
    CATCH cx_step1_error INTO DATA(lx_step1).
      " 包装异常
      RAISE EXCEPTION TYPE cx_process_error
        EXPORTING
          textid   = cx_process_error=>processing_failed
          previous = lx_step1
          step     = 'STEP1'.
          
  ENDTRY.
ENDMETHOD.
10.可恢复异常 (Resumable Exceptions)
ABAP 复制代码
" 定义可恢复异常
CLASS cx_resumable_exception DEFINITION
  INHERITING FROM cx_no_check
  RESUMABLE FINAL.  " RESUMABLE 关键字

METHOD process_with_resume.
  TRY.
      RAISE RESUMABLE EXCEPTION TYPE cx_resumable_exception
        EXPORTING
          textid = cx_resumable_exception=>resume_required.
      
    CATCH BEFORE UNWIND cx_resumable_exception INTO DATA(lx_ex).
      " BEFORE UNWIND 在栈展开前执行
      IF can_resume = abap_true.
        RESUME.  " 恢复执行
      ENDIF.
  ENDTRY.
  
  " 如果恢复了,继续执行这里
  WRITE: / 'Execution resumed'.
ENDMETHOD.
10.推荐使用RAISE
ABAP 复制代码
" 1. 使用具体的异常类型
RAISE EXCEPTION TYPE cx_sy_zerodivide.  " 而不是 cx_root

" 2. 提供有意义的错误信息
RAISE EXCEPTION TYPE zcx_validation_error
  EXPORTING
    textid    = zcx_validation_error=>invalid_email
    email     = lv_email
    fieldname = 'EMAIL'.

" 3. 保留原始异常链
CATCH cx_sy_conversion_error INTO DATA(lx_conv).
  RAISE EXCEPTION TYPE zcx_business_error
    EXPORTING
      previous = lx_conv
      textid   = zcx_business_error=>conversion_failed.

" 4. 在方法签名中声明异常
METHODS process
  RAISING
    cx_sy_file_io_error
    zcx_business_error.
11.性能注意事项
  • 异常处理比正常返回开销大
  • 避免在循环中频繁抛出异常
  • 对于可预期的错误,使用返回值检查
  • 异常应用于真正的异常情况

总结:RAISE EXCEPTION是 ABAP 中处理错误情况的标准方式,应该优先于设置 sy-subrc的老式错误处理。

相关推荐
cncdns-james9 小时前
SAP Hana Studio备份生产机数据库——【认识SAP HANA Studio篇】
数据库·sap·sap hana studio
SAP小崔说事儿1 天前
自研Rise系列之ERP——基于SAPB1 的前端业务系统
sap·erp·sap b1·business one·b1·思爱普·自研erp
淋了一场太阳雨1 天前
SAP LSMW (二) - Batch Input Recording
sap·batch·lsmw
SAP小崔说事儿2 天前
SAP B1 库龄分析报表(SQL版本&非批次管理)
数据库·sql·sap·sap b1·business one·批次管理·库龄分析
产品日记2 天前
SAP报错处理:有关最后完成得会计年度的信息不完整
经验分享·sap·sap gr·group reporting
ABAP_小欧6 天前
SAP 取工单无抬头料号取计划成本 COSP COSS
sap·abap
goyeer6 天前
11.[SAP ABAP] Package
sap·abap
阿达_优阅达6 天前
集成方案 | 通过 Xtract Universal,将 SAP 数据无缝接入 Power BI 与微软 Fabric
运维·microsoft·sap·fabric·theobald
goyeer7 天前
10.[SAP ABAP] 字符串
sap·abap