ZBCC0006-ADBC reuse routine-SE38(I類型)

*&---------------------------------------------------------------------*
*& INCLUDE          ZBCC0006: ADBC reuse routine
*&---------------------------------------------------------------------*

DATA: %g_er_msg TYPE string. "Error mesage global use

***  DB connection name
DATA: %g_dbcon_name  TYPE dbcon_name VALUE 'ORDB'. "default DB connect

***  DB Schema name
DATA: %g_schema_name  TYPE dbadbc_schema_name. "default schema

* ADBC - Handling the Connection and statements
DATA: %o_conn     TYPE REF TO cl_sql_connection.






*&---------------------------------------------------------------------*
*& Macro
*&---------------------------------------------------------------------*
DEFINE check_error.
  IF %g_er_msg IS NOT INITIAL.
    e_msg = %g_er_msg.
    e_status = 'E'.

    IF %o_conn IS NOT INITIAL.
      %o_conn->close( ).
    ENDIF.

    RETURN.
  ENDIF. "IF %g_er_msg IS NOT INITIAL
END-OF-DEFINITION.




******
*&---------------------------------------------------------------------*
*& Form CONNECT_EXT_DB
*&---------------------------------------------------------------------*
*& connect to external DB  -> return %o_conn
*&---------------------------------------------------------------------*
FORM connect_ext_db  USING    f_dbcon_name
                              f_schema_name.
*** exception handle
  DATA: lo_cx_sql  TYPE REF TO cx_sql_exception.

*************************

  CLEAR: %g_er_msg.

  IF f_dbcon_name IS NOT INITIAL.
    %g_dbcon_name = f_dbcon_name."DB connect Name
  ENDIF.

  IF f_schema_name IS NOT INITIAL.
    %g_schema_name = f_schema_name."DB schema Name
  ENDIF.

  TRY.
***    connect to external DB
      %o_conn = cl_sql_connection=>get_connection( %g_dbcon_name ).

    CATCH cx_sql_exception INTO lo_cx_sql.
      %g_er_msg = lo_cx_sql->get_text( ).
      IF %g_er_msg IS INITIAL.
        %g_er_msg = `Connect to DB: ` &&  %g_dbcon_name  && ' Error'.
      ENDIF.
  ENDTRY.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form GET_COLUMNS_INFO
*&---------------------------------------------------------------------*
*& 取得 ORACLE DB TABLE 欄位的設定 + primary key 欄位
*&---------------------------------------------------------------------*
FORM get_columns_info  USING   ft_col    TYPE adbc_tabcol_descr_tab "回傳的 欄位 ITAB
                               ft_pk_col TYPE adbc_column_tab  "回傳的 KEY FIELD 欄位 ITAB
                               f_mid_table  "oracle table name
                               .

  DATA: lo_metadata TYPE REF TO cl_sql_metadata.

  DATA:
    lt_tabdescr_tab TYPE adbc_table_descr_tab,
    lt_schema_rgtab TYPE adbc_schema_name_rgtab,
    lt_table_rgtab  TYPE adbc_name_rgtab.

*  FIELD-SYMBOLS:
*    <lfs_tab_rg>   LIKE LINE OF lt_table_rgtab,
*    <lfs_tabdescr> LIKE LINE OF lt_tabdescr_tab,
*    <lfs_schema>   TYPE adbc_schema_name,
*    <lfs_tabname>  TYPE adbc_name.

  DATA: l_schema TYPE adbc_name.
  DATA: l_table TYPE adbc_name.

  DATA  l_pk_name       TYPE adbc_name.


****  exception
  DATA: lo_sqlerr       TYPE REF TO cx_sql_exception.

**********************************************************
  CLEAR: %g_er_msg.
* create a metadata object
  lo_metadata = %o_conn->get_metadata( ).

* search for the specified table in the database catalog; because
* the method GET_TABLES expects a range table for the table search
* we create one with an EQ-condition
  TRY.
***  set schema
      APPEND INITIAL LINE TO lt_schema_rgtab ASSIGNING FIELD-SYMBOL(<lfs_schema>).
      <lfs_schema>-sign   = 'I'.
      <lfs_schema>-option = 'EQ'.
      <lfs_schema>-low    =  %g_schema_name.

****  set table
      APPEND INITIAL LINE TO lt_table_rgtab ASSIGNING FIELD-SYMBOL(<lfs_table>).
      <lfs_table>-sign = 'I'.
      <lfs_table>-option = 'EQ'.
      <lfs_table>-low = f_mid_table.

      CALL METHOD lo_metadata->get_tables
        EXPORTING
          schema_rgtab    = lt_schema_rgtab
          table_rgtab     = lt_table_rgtab
        IMPORTING
          table_descr_tab = lt_tabdescr_tab.

*       check if the table was found in the catalog (this means that the
*       internal table returned contains at least one row)
      READ TABLE lt_tabdescr_tab INDEX 1 ASSIGNING FIELD-SYMBOL(<lfs_tabdescr>).
      IF sy-subrc <> 0.
        %g_er_msg = `Table: ` && f_mid_table && ` not found in Schema: ` && %g_schema_name.
        RETURN.
      ENDIF.

      l_schema = <lfs_tabdescr>-schema.
      l_table = <lfs_tabdescr>-table_name.

**     get all columns of the table/view from the database catalog
      CALL METHOD lo_metadata->get_columns
        EXPORTING
          schema_name = l_schema
          table_name  = l_table
        IMPORTING
          column_tab  = ft_col.
*     Check if returned table is empty
      READ TABLE ft_col INDEX 1 TRANSPORTING NO FIELDS.
      IF sy-subrc <> 0.
        %g_er_msg = `Table: ` && l_table && `DB catalog not found!!`.
        RETURN.
      ENDIF.

      SORT ft_col BY position.

*****  get primary key field
      CALL METHOD lo_metadata->get_primary_keys
        EXPORTING
          schema_name      = l_schema
          table_name       = l_table
        IMPORTING
          primary_key_name = l_pk_name
          primary_key_tab  = ft_pk_col.
      READ TABLE ft_pk_col INDEX 1 TRANSPORTING NO FIELDS.
      IF sy-subrc <> 0.
        %g_er_msg = `Table: ` && l_table && `Primary Key not found!!`.
        RETURN.
      ENDIF.


    CATCH cx_sql_exception INTO lo_sqlerr.

      %g_er_msg = 'Table ' && l_table && ` get metadat error: `
                  && lo_sqlerr->sql_code && ` `
                  && lo_sqlerr->get_text( ).                "#EC NOTEXT
  ENDTRY.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form GEN_INS_SQL_AND_WA
*&---------------------------------------------------------------------*
*& 產生 insert filed / value list,  work area reference
*&---------------------------------------------------------------------*
FORM gen_ins_sql_and_wa  USING    ft_col  TYPE adbc_tabcol_descr_tab
                                  f_fields  "field list
                                  f_values  "value list
                                  fr_wa
                                        .

  DATA: l_col LIKE LINE OF ft_col.

  DATA: l_tabix LIKE sy-tabix.
  DATA: lt_comp TYPE abap_component_tab
        WITH HEADER LINE.

  DATA: lo_stru_desc  TYPE REF TO cl_abap_structdescr.

  DATA: l_value TYPE string.

  DATA: l_fields TYPE string.   "Duke

***********************
  CLEAR: %g_er_msg.
  CLEAR: f_fields, f_values.

  LOOP AT ft_col INTO l_col.

    ADD 1 TO l_tabix.

    IF l_col-ddic_type = 'DATS'.
      l_value =  `TO_DATE(?, 'YYYYMMDD')`.
**----->>> change by tommy 2021/03/05
*      l_fields = `TO_CHAR(` && l_col-column_name && `, 'YYYYMMDD')`.
      l_fields = l_col-column_name.
**-----<<< change by tommy 2021/03/05
    ELSE.
      l_value = '?'.
      l_fields = l_col-column_name.
    ENDIF.

    IF l_tabix = 1.
*      f_fields = l_col-column_name.
      f_fields = l_fields.
      f_values = l_value.
    ELSE.
*      f_fields = f_fields && `, ` && l_col-column_name.
      f_fields = f_fields && `, ` && l_fields.
      f_values =  f_values && `, ` && l_value.
    ENDIF.

****  WA field 描述
    CLEAR: lt_comp.
    lt_comp-name =  l_col-column_name.
    PERFORM set_type USING lt_comp-type l_col .
    IF %g_er_msg IS NOT INITIAL.
      RETURN.
    ENDIF.
    APPEND lt_comp.

  ENDLOOP."LOOP AT %t_coldescr


*****    work area
  lo_stru_desc = cl_abap_structdescr=>create( lt_comp[] ).
  CREATE DATA fr_wa TYPE HANDLE lo_stru_desc.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form SET_TYPE
*&---------------------------------------------------------------------*
*&  data type mapping
*&---------------------------------------------------------------------*
FORM set_type  USING    f_type
                        f_coldescr TYPE   adbc_tabcol_descr.

  DATA: l_length TYPE i.
  DATA: l_decimals TYPE i.
*************************

  l_length  = f_coldescr-ddic_length.
  l_decimals = f_coldescr-ddic_decimals.

  CASE f_coldescr-ddic_type.
    WHEN 'NUMC' ."N
      f_type = cl_abap_elemdescr=>get_n( l_length ).

    WHEN 'CHAR'.
      f_type = cl_abap_elemdescr=>get_c( l_length ).

    WHEN 'DATS'."D
      f_type = cl_abap_elemdescr=>get_d( ).

    WHEN  'TIMS'."T
      f_type = cl_abap_elemdescr=>get_t( ).

    WHEN 'INT2'  ."I
      f_type = cl_abap_elemdescr=>get_int2( ).

    WHEN  'INT4'    ."I
      f_type = cl_abap_elemdescr=>get_i( ).

    WHEN  'INT8' ."I
      f_type = cl_abap_elemdescr=>get_int8( ).

    WHEN 'DEC'."P

      f_type = cl_abap_elemdescr=>get_p( p_length = ( l_length / 2  + 1 )
      p_decimals = l_decimals
      ).

    WHEN 'RAW'.
      f_type = cl_abap_elemdescr=>get_x( p_length = l_length ).
    WHEN 'FLTP'.
      f_type = cl_abap_elemdescr=>get_f( ).

    WHEN OTHERS.

      %g_er_msg  = `DDIC Type: ` && f_coldescr-ddic_type && `not process mapping, check FORM SET_TYPE!!`.

  ENDCASE."CASE l_comp-type_kind.

ENDFORM.                    " SET_TYPE
*&---------------------------------------------------------------------*
*& Form GEN_UPD_DEL_WHERE_AND_WA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM gen_upd_del_where_and_wa  USING    ft_pk_col  TYPE adbc_column_tab "primary key field list
                                        ft_col TYPE adbc_tabcol_descr_tab "table field list
                                        f_where
                                        fr_wa.


  DATA: l_pk_col LIKE LINE OF ft_pk_col.
  DATA: l_col LIKE LINE OF ft_col.

  DATA: lt_comp TYPE abap_component_tab
        WITH HEADER LINE.
  DATA: l_tabix LIKE sy-tabix.
  DATA: lo_stru_desc  TYPE REF TO cl_abap_structdescr.

  DATA: l_value TYPE string.

*******************

  CLEAR: f_where.

  LOOP AT ft_pk_col INTO l_pk_col.
    ADD 1 TO l_tabix.

****  update/delete where condition
    READ TABLE ft_col INTO l_col
      WITH KEY column_name = l_pk_col.

    IF l_col-ddic_type = 'DATS'.
      l_value =  `TO_DATE(?, 'YYYYMMDD')`.
    ELSE.
      l_value = '?'.
    ENDIF.

    IF l_tabix = 1.
      f_where = l_pk_col && ` = ` && l_value.
    ELSE.
      f_where = f_where && ` AND ` && l_pk_col && ` = ` && l_value.
    ENDIF.

****  WA 描述
    CLEAR: lt_comp.
    lt_comp-name = l_col-column_name.
    PERFORM set_type USING lt_comp-type l_col.
    IF %g_er_msg IS NOT INITIAL.
      RETURN.
    ENDIF.

    APPEND lt_comp.

  ENDLOOP."LOOP AT %t_pk_col


** insert/delete work area
  lo_stru_desc = cl_abap_structdescr=>create( lt_comp[] ).
  CREATE DATA fr_wa TYPE HANDLE lo_stru_desc.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_PRE_STAT_OBJ_R
*&---------------------------------------------------------------------*
*& create statemant object and set parameter reference
*&---------------------------------------------------------------------*
FORM create_pre_stat_obj_r  USING    f_query
                                     fo_pre_stat TYPE REF TO cl_sql_prepared_statement
                                     f_st TYPE REF TO data. "WA
  DATA: lo_cx_root TYPE REF TO cx_root.
********************
  CLEAR: %g_er_msg.
  TRY .
**** SQL statemant create
      fo_pre_stat = %o_conn->prepare_statement( f_query ).
*** QUERY 參數欄位 binding
      fo_pre_stat->set_param_struct( f_st ).
    CATCH cx_sql_exception
           cx_parameter_invalid
      INTO lo_cx_root.
      %g_er_msg = lo_cx_root->get_text( ).
      IF %g_er_msg IS INITIAL.
        %g_er_msg = 'Create Query Object Error!'.
      ENDIF.
  ENDTRY.

ENDFORM.                    " CREATE_PRE_STAT_OBJ_R
*&---------------------------------------------------------------------*
*& Form CREATE_INSERT_STATEMENT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LT_COL_M
*&      --> LT_PK_COL_M
*&      --> I_MDBNAME_M
*&      --> LO_INS_STAT_M
*&      --> LR_INS_WA_M
*&---------------------------------------------------------------------*
FORM create_insert_statement  USING    p_lt_col_m
                                       p_lt_pk_col_m
                                       p_i_mdbname_m
                                       p_lo_ins_stat_m
                                       p_lr_ins_wa_m.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_INSERT_STATEMENT_OBJ
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*&      --> LT_COL_M
*&      --> I_MDBNAME_M
*&      --> LO_INS_STAT_M
*&      --> LR_INS_WA_M
*&---------------------------------------------------------------------*
FORM create_insert_statement_obj  USING   ft_pk_col TYPE adbc_column_tab  "return table primary key field list
                                          ft_col TYPE adbc_tabcol_descr_tab "return table field list
                                           f_mdbname "oracle table name
                                           fo_ins_stat TYPE REF TO cl_sql_prepared_statement
                                           fr_st TYPE REF TO data."WA reference

  DATA: l_fields_ins TYPE string."insert field list
  DATA: l_values_ins TYPE string."insert value list

  DATA: l_ins_query  TYPE string.

********************************

****  1. matadata
****  get oracle master table field and primary key field
  PERFORM get_columns_info USING ft_col ft_pk_col
                    f_mdbname .
  IF %g_er_msg IS NOT INITIAL.
****   metadata error
*    e_msg = %g_er_msg.
*    e_status = 'E'.
    RETURN.
  ENDIF. "IF %g_er_msg IS NOT INITIAL

****   2. insert field list / value list / WA
  PERFORM gen_ins_sql_and_wa
       USING ft_col
             l_fields_ins l_values_ins fr_st
             .
  IF %g_er_msg IS NOT INITIAL.
****   generate WA error
*    e_msg = %g_er_msg.
*    e_status = 'E'.
    RETURN.
  ENDIF. "IF %g_er_msg IS NOT INITIAL


****  3. insert query statemant object
  l_ins_query = `INSERT INTO ` &&  %g_schema_name && `.`  && f_mdbname
             && ` ( `  && l_fields_ins && ` ) VALUES ( `
             && l_values_ins && ` )`.

  PERFORM create_pre_stat_obj_r
     USING l_ins_query fo_ins_stat fr_st.
  IF %g_er_msg IS NOT INITIAL.
*    e_msg = %g_er_msg.
*    e_status = 'E'.
    RETURN.
  ENDIF.


ENDFORM.
*&---------------------------------------------------------------------*
*& Form CREATE_DELETE_STATEMENT_OBJ
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM create_delete_statement_obj  USING    f_del_where
                                           f_mdbname
                                           fo_del_stat TYPE REF TO cl_sql_prepared_statement
                                           fr_st TYPE REF TO data."WA reference

  DATA: l_del_query  TYPE string.

*****************************
  CLEAR: %g_er_msg.

  l_del_query = `DELETE FROM ` &&  %g_schema_name && `.`  && f_mdbname
               && ` WHERE ` && f_del_where.

  PERFORM create_pre_stat_obj_r
     USING l_del_query fo_del_stat  fr_st.
  IF %g_er_msg IS NOT INITIAL.
*    e_msg = %g_er_msg.
*    e_status = 'E'.
    RETURN.
  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form GEN_SAP_DEL_WHERE
*&---------------------------------------------------------------------*
*& update or delete where clause
*&---------------------------------------------------------------------*
FORM gen_sap_del_where  USING    ft_pk_col  TYPE adbc_column_tab
                                 f_data
                                f_where.

  DATA: l_pk_col LIKE LINE OF ft_pk_col.
  DATA: l_tabix LIKE sy-tabix.
  DATA: l_value TYPE string.
  FIELD-SYMBOLS: <lfs>.
************************************
  LOOP AT ft_pk_col INTO l_pk_col.

****  update/delete where condition
    ADD 1 TO l_tabix.

    ASSIGN COMPONENT l_pk_col OF STRUCTURE f_data TO <lfs>.

    IF l_tabix = 1.
      f_where = l_pk_col && ` = '` && <lfs> && `'`.
    ELSE.
      f_where = f_where && ` AND ` && l_pk_col && ` = '` && <lfs>  && `'`.
    ENDIF.

  ENDLOOP."LOOP AT %t_pk_col

ENDFORM.
*&---------------------------------------------------------------------*
*& Form GEN_UPD_DEL_WHERE_AND_WA_BY_LV
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM gen_upd_del_where_and_wa_by_lv  USING
                                        ft_key_col  TYPE adbc_column_tab "primary key field list
                                        ft_col TYPE adbc_tabcol_descr_tab "table field list
                                        f_key_level
                                        f_where
                                        fr_wa.


  DATA: l_key_col LIKE LINE OF ft_key_col.
  DATA: l_col LIKE LINE OF ft_col.

  DATA: lt_comp TYPE abap_component_tab
        WITH HEADER LINE.
  DATA: l_tabix LIKE sy-tabix.
  DATA: lo_stru_desc  TYPE REF TO cl_abap_structdescr.

  DATA: l_value TYPE string.

*******************

  CLEAR: f_where.

  LOOP AT ft_key_col INTO l_key_col TO f_key_level.
    ADD 1 TO l_tabix.

****  update/delete where condition
    READ TABLE ft_col INTO l_col
      WITH KEY column_name = l_key_col.

    IF l_col-ddic_type = 'DATS'.
      l_value =  `TO_DATE(?, 'YYYYMMDD')`.
    ELSE.
      l_value = '?'.
    ENDIF.

    IF l_tabix = 1.
      f_where = l_key_col && ` = ` && l_value.
    ELSE.
      f_where = f_where && ` AND ` && l_key_col && ` = ` && l_value.
    ENDIF.

****  WA 描述
    CLEAR: lt_comp.
    lt_comp-name = l_col-column_name.
    PERFORM set_type USING lt_comp-type l_col.
    IF %g_er_msg IS NOT INITIAL.
      RETURN.
    ENDIF.

    APPEND lt_comp.

  ENDLOOP."LOOP AT %t_pk_col


** insert/delete work area
  lo_stru_desc = cl_abap_structdescr=>create( lt_comp[] ).
  CREATE DATA fr_wa TYPE HANDLE lo_stru_desc.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form GEN_SAP_DEL_WHERE_MULTI
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
FORM gen_sap_del_where_multi  USING    ft_key_col  TYPE adbc_column_tab
                                        f_key_level
                                f_wa_name
                                f_where.

  DATA: l_key_col LIKE LINE OF ft_key_col.
  DATA: l_tabix LIKE sy-tabix.
*  DATA: l_value TYPE string.
*  FIELD-SYMBOLS: <lfs>.
************************************

  LOOP AT ft_key_col INTO l_key_col TO f_key_level.

****  update/delete where condition
    ADD 1 TO l_tabix.

    IF l_tabix = 1.
      f_where = l_key_col && ` = @` && f_wa_name && `-` && l_key_col.
    ELSE.
      f_where = f_where && ` AND ` && l_key_col && ` = @` && f_wa_name && `-` && l_key_col.
    ENDIF.

  ENDLOOP."LOOP AT %t_pk_col

ENDFORM.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值