SAP 动态 SELECT 语句

举报
雨绸缪 发表于 2023/07/31 17:11:11 2023/07/31
【摘要】 我们可以动态选择并创建动态表。这也可以通过不同的方式实现,但这基本上是一个关于如何实现动态选择语句的例子。强烈警告:虽然这非常有用,但要确保你的代码安全,在你的动态程序上添加授权检查,防止任何注入。PARAMETERS: p_tab TYPE tabname, p_matnr TYPE matnr.TYPES: BEGIN OF ty_list, n...

我们可以动态选择并创建动态表。这也可以通过不同的方式实现,但这基本上是一个关于如何实现动态选择语句的例子。

强烈警告:虽然这非常有用,但要确保你的代码安全,在你的动态程序上添加授权检查,防止任何注入。

PARAMETERS: p_tab   TYPE tabname,
            p_matnr TYPE matnr.

TYPES: BEGIN OF ty_list,
         name  TYPE tabname,
         r_str TYPE REF TO data,
         r_tbl TYPE REF TO data,
       END OF ty_list.

DATA: lt_list         TYPE STANDARD TABLE OF ty_list.

DATA: lo_structure  TYPE REF TO cl_abap_structdescr,
      lo_table      TYPE REF TO cl_abap_tabledescr,
      lt_fields     TYPE STANDARD TABLE OF fieldname,
      lt_CONDTAB    TYPE STANDARD TABLE OF hrcond,
      lt_where      TYPE STANDARD TABLE OF string,
      lr_data       TYPE REF TO data,
      lr_table_data TYPE REF TO data.

FIELD-SYMBOLS: <lfs_table> TYPE STANDARD TABLE.


lo_structure ?= cl_abap_structdescr=>describe_by_name( p_name = p_tab ).
CREATE DATA lr_data TYPE HANDLE lo_structure.

lo_table ?= cl_abap_tabledescr=>create(
              p_line_type  = lo_structure                   " Line Type
*                p_table_kind = tablekind_std      " Table Category (STANDARD, SORTED, HASHED)
*                p_unique     = abap_false         " Uniqueness of the Key
*                p_key        =                    " Key table
*                p_key_kind   = keydefkind_default " Key category
            ).

CREATE DATA lr_table_data TYPE HANDLE lo_table.


ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_structure>).
ASSIGN lr_table_data->* TO FIELD-SYMBOL(<lfs_table_data>).

lt_condtab = VALUE #( ( field = 'MATNR' opera = 'EQ' low = p_matnr ) ).

IF <lfs_table_data> IS ASSIGNED.

  IF p_tab EQ 'MARA'.
    lt_fields = VALUE #( ( 'MATNR'  ) ).

    CALL FUNCTION 'RH_DYNAMIC_WHERE_BUILD'
      EXPORTING
        dbtable         = p_Tab
      TABLES
        condtab         = lt_condtab
        where_clause    = lt_where
      EXCEPTIONS
        empty_condtab   = 1
        no_db_field     = 2
        unknown_db      = 3
        wrong_condition = 4
        OTHERS          = 5.

    SELECT (lt_fields)
      FROM (p_tab)
     WHERE (lt_where)
      INTO CORRESPONDING FIELDS OF TABLE @<lfs_table_data>.

    " Do something

  ENDIF.

ENDIF.

引用变量

正如你所注意到的,这在上面的例子中已经使用过了。在使用数据引用的情况下,创建动态对象是没有限制的。

例如,你可以用数据引用创建一个内部表。在下面的例子中,你可以通过对动态结构和表的数据引用来创建一个类型化的内部表。

TYPES: BEGIN OF ty_list,
           name   TYPE tabname,
           r_str  TYPE REF TO data,
           r_tbl  TYPE REF TO data,
         END OF ty_list. 
         
  DATA: lt_list         TYPE STANDARD TABLE OF ty_list. 

数据引用也可以通过方法或函数模块与结构良好的引用变量进行传递。如果你真的需要调用动态数据,最好的方法是通过参考变量。

PARAMETERS: p_tab   TYPE tabname.

 CLASS lcl_main DEFINITION.

   PUBLIC SECTION.

    CLASS-METHODS: set_data   CHANGING o_tbl   TYPE REF TO data.

 ENDCLASS.

  TYPES: BEGIN OF ty_list,
           name   TYPE tabname,
           r_str  TYPE REF TO data,
           r_tbl  TYPE REF TO data,
         END OF ty_list.

  DATA: lt_list         TYPE STANDARD TABLE OF ty_list.

  DATA: lo_structure    TYPE REF TO cl_abap_structdescr,
        lo_table        TYPE REF TO cl_abap_tabledescr,
        lr_data         TYPE REF TO data,
        lr_table_data   TYPE REF TO data.

  FIELD-SYMBOLS: <lfs_table> TYPE STANDARD TABLE.


  lo_structure ?= cl_abap_structdescr=>describe_by_name( p_name = p_tab ).
  CREATE DATA lr_data TYPE HANDLE lo_structure.

  lo_table ?= cl_abap_tabledescr=>create(
                p_line_type  = lo_structure                   " Line Type
*                p_table_kind = tablekind_std      " Table Category (STANDARD, SORTED, HASHED)
*                p_unique     = abap_false         " Uniqueness of the Key
*                p_key        =                    " Key table
*                p_key_kind   = keydefkind_default " Key category
              ).

  CREATE DATA lr_table_data TYPE HANDLE lo_table.


  ASSIGN lr_data->* TO FIELD-SYMBOL(<lfs_structure>).
  ASSIGN lr_table_data->* TO FIELD-SYMBOL(<lfs_table_data>).

  IF <lfs_table_data> IS ASSIGNED.
    lcl_main=>set_data(
      CHANGING
        o_tbl = lr_table_data
    ).
  ENDIF.

 CLASS lcl_main IMPLEMENTATION.

   METHOD set_data.
     FIELD-SYMBOLS: <lfs_data> TYPE STANDARD TABLE.

     ASSIGN o_tbl->* TO <lfs_data>.
     IF <lfs_data> IS ASSIGNED.
       " Do something
     ENDIF.

   ENDMETHOD.

 ENDCLASS.

动态方法

ABAP OO 概念的最好方法之一,特别是在某些方面的多态性,是使用类接口。

它的一个很好的例子是当你想根据配置运行不同的逻辑时。例如,你有一个程序,既可以发送至 excelrest 服务,也可以发送至本地服务器中的平面文件,同时使其可配置,标准化的最佳实践方法是使用类 Interfaces。

DATA: lo_adapter    TYPE REF TO zif_adapter,
          ls_data       TYPE ty_data. 

    IF ms_adapter-s_adapter-call_class IS NOT INITIAL.
      TRY.
          CREATE OBJECT lo_adapter TYPE (ms_adapter-s_adapter-call_class).
	  IF lo_adapter IS BOUND.
		
	    lo_adapter->send( CHANGING is_data = ls_data ). 

          ENDIF. 

        CATCH cx_sy_dyn_call_illegal_method.
        CATCH cx_sy_create_object_error.
      ENDTRY.
    ENDIF. 

类接口:

" Class #1. Send via Email 
CLASS zcl_email definition
  public
  final
  create public .

   PUBLIC SECTION.
   
    INTERFACES: zif_adapter.
   
   PROTECTED SECTION. 
   PRIVATE SECTION. 

 ENDCLASS.

 CLASS lcl_main IMPLEMENTATION.

   
   METHOD zif_adapter~send. 
     " Send via email
   ENDMETHOD. 


 ENDCLASS.
 
" Class #2. Send via FTP
  CLASS zcl_ftp definition
  public
  final
  create public .

   PUBLIC SECTION.
   
    INTERFACES: zif_adapter.
   
   PROTECTED SECTION. 
   PRIVATE SECTION. 

 ENDCLASS.

 CLASS lcl_main IMPLEMENTATION.

   
   METHOD zif_adapter~send. 
     " Send to ftp server
   ENDMETHOD. 


 ENDCLASS.
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。