ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • AMDP 동적 JSON 파라미터
    SAP 2026. 6. 17. 21:00

    amdp_json_dynamic_param.html
    0.02MB

     

     

    AMDP 동적 JSON 파라미터 — ko_001~150

    AMDP 동적 JSON 파라미터 — ko_001 ~ ko_150

    필드명 규칙(ko_NNN)을 활용한 FIELD-SYMBOLS 동적 매핑 → JSON 직렬화 → AMDP 전달
    ① 구조체 정의
    ko_001~150
    ② FIELD-SYMBOLS
    동적 매핑
    ③ JSON
    직렬화
    ④ AMDP
    호출
    ⑤ SQLScript
    JSON_VALUE()

    1 구조체 정의 — ko_001 ~ ko_150

    💡 필드명이 ko_001 ~ ko_150으로 규칙적이므로 FIELD-SYMBOLS로 동적 접근 가능.

    💡 모든 값을 char50으로 통일하면 동적 처리가 가장 단순해짐.

    * ======================================================
    * 구조체 정의 (SE11 등록 또는 로컬 TYPES)
    * 필드: ko_001 ~ ko_150, 전부 CHAR50 (값은 string으로 통일)
    *======================================================
    TYPES: BEGIN OF zst_ko_param,
      ko_001 TYPE char50,  ko_002 TYPE char50,  ko_003 TYPE char50,
      ko_004 TYPE char50,  ko_005 TYPE char50,  ko_006 TYPE char50,
      ko_007 TYPE char50,  ko_008 TYPE char50,  ko_009 TYPE char50,
      ko_010 TYPE char50,  ko_011 TYPE char50,  ko_012 TYPE char50,
      ko_013 TYPE char50,  ko_014 TYPE char50,  ko_015 TYPE char50,
      ko_016 TYPE char50,  ko_017 TYPE char50,  ko_018 TYPE char50,
      ko_019 TYPE char50,  ko_020 TYPE char50,  ko_021 TYPE char50,
      ko_022 TYPE char50,  ko_023 TYPE char50,  ko_024 TYPE char50,
      ko_025 TYPE char50,  ko_026 TYPE char50,  ko_027 TYPE char50,
      ko_028 TYPE char50,  ko_029 TYPE char50,  ko_030 TYPE char50,
      ko_031 TYPE char50,  ko_032 TYPE char50,  ko_033 TYPE char50,
      ko_034 TYPE char50,  ko_035 TYPE char50,  ko_036 TYPE char50,
      ko_037 TYPE char50,  ko_038 TYPE char50,  ko_039 TYPE char50,
      ko_040 TYPE char50,  ko_041 TYPE char50,  ko_042 TYPE char50,
      ko_043 TYPE char50,  ko_044 TYPE char50,  ko_045 TYPE char50,
      ko_046 TYPE char50,  ko_047 TYPE char50,  ko_048 TYPE char50,
      ko_049 TYPE char50,  ko_050 TYPE char50,  ko_051 TYPE char50,
      ko_052 TYPE char50,  ko_053 TYPE char50,  ko_054 TYPE char50,
      ko_055 TYPE char50,  ko_056 TYPE char50,  ko_057 TYPE char50,
      ko_058 TYPE char50,  ko_059 TYPE char50,  ko_060 TYPE char50,
      ko_061 TYPE char50,  ko_062 TYPE char50,  ko_063 TYPE char50,
      ko_064 TYPE char50,  ko_065 TYPE char50,  ko_066 TYPE char50,
      ko_067 TYPE char50,  ko_068 TYPE char50,  ko_069 TYPE char50,
      ko_070 TYPE char50,  ko_071 TYPE char50,  ko_072 TYPE char50,
      ko_073 TYPE char50,  ko_074 TYPE char50,  ko_075 TYPE char50,
      ko_076 TYPE char50,  ko_077 TYPE char50,  ko_078 TYPE char50,
      ko_079 TYPE char50,  ko_080 TYPE char50,  ko_081 TYPE char50,
      ko_082 TYPE char50,  ko_083 TYPE char50,  ko_084 TYPE char50,
      ko_085 TYPE char50,  ko_086 TYPE char50,  ko_087 TYPE char50,
      ko_088 TYPE char50,  ko_089 TYPE char50,  ko_090 TYPE char50,
      ko_091 TYPE char50,  ko_092 TYPE char50,  ko_093 TYPE char50,
      ko_094 TYPE char50,  ko_095 TYPE char50,  ko_096 TYPE char50,
      ko_097 TYPE char50,  ko_098 TYPE char50,  ko_099 TYPE char50,
      ko_100 TYPE char50,  ko_101 TYPE char50,  ko_102 TYPE char50,
      ko_103 TYPE char50,  ko_104 TYPE char50,  ko_105 TYPE char50,
      ko_106 TYPE char50,  ko_107 TYPE char50,  ko_108 TYPE char50,
      ko_109 TYPE char50,  ko_110 TYPE char50,  ko_111 TYPE char50,
      ko_112 TYPE char50,  ko_113 TYPE char50,  ko_114 TYPE char50,
      ko_115 TYPE char50,  ko_116 TYPE char50,  ko_117 TYPE char50,
      ko_118 TYPE char50,  ko_119 TYPE char50,  ko_120 TYPE char50,
      ko_121 TYPE char50,  ko_122 TYPE char50,  ko_123 TYPE char50,
      ko_124 TYPE char50,  ko_125 TYPE char50,  ko_126 TYPE char50,
      ko_127 TYPE char50,  ko_128 TYPE char50,  ko_129 TYPE char50,
      ko_130 TYPE char50,  ko_131 TYPE char50,  ko_132 TYPE char50,
      ko_133 TYPE char50,  ko_134 TYPE char50,  ko_135 TYPE char50,
      ko_136 TYPE char50,  ko_137 TYPE char50,  ko_138 TYPE char50,
      ko_139 TYPE char50,  ko_140 TYPE char50,  ko_141 TYPE char50,
      ko_142 TYPE char50,  ko_143 TYPE char50,  ko_144 TYPE char50,
      ko_145 TYPE char50,  ko_146 TYPE char50,  ko_147 TYPE char50,
      ko_148 TYPE char50,  ko_149 TYPE char50,  ko_150 TYPE char50,
    END OF zst_ko_param.

    2 동적 값 매핑 — FIELD-SYMBOLS 활용

    💡 값을 담은 itab(key-index, value)을 순회하며 ASSIGN COMPONENT로 구조체 필드에 동적 세팅.

    💡 값이 없는 필드는 자동으로 INITIAL(공백) 상태 유지.

    * ======================================================
    * 동적 값 매핑 헬퍼 메서드 (독립 클래스 or 로컬 사용)
    *======================================================
    
    * ① 값 목록 정의 (인덱스 + 값 쌍)
    TYPES: BEGIN OF ty_val_entry,
             idx TYPE i,         " 1 ~ 150
             val TYPE char50,    " 세팅할 값
           END OF ty_val_entry,
           tt_val_entry TYPE STANDARD TABLE OF ty_val_entry
                        WITH DEFAULT KEY.
    
    * ② 동적 매핑 메서드
    CLASS-METHODS map_to_struct
      IMPORTING
        it_values  TYPE tt_val_entry       " (idx=1, val='1000'), (idx=5, val='A')...
      RETURNING
        VALUE(rs_param) TYPE zst_ko_param. " 구조체 리턴
    
    * ③ 구현부
    METHOD map_to_struct.
    
      FIELD-SYMBOLS: <fs_field> TYPE char50.
      DATA lv_fname TYPE string.
    
      LOOP AT it_values INTO DATA(ls_entry).
    
        * ko_001 형식으로 필드명 동적 생성 (3자리 zero-padding)
        lv_fname = |KO_{ ls_entry-idx WIDTH = 3 FILL = '0' }|.
    
        * 구조체 필드에 동적 할당
        ASSIGN COMPONENT lv_fname
          OF STRUCTURE rs_param
          TO <fs_field>.
    
        IF <fs_field> IS ASSIGNED.
          <fs_field> = ls_entry-val.
          UNASSIGN <fs_field>.
        ENDIF.
    
      ENDLOOP.
    
    ENDMETHOD.

    3 호출부 — 값 세팅 + JSON 직렬화 + AMDP 호출

    * ======================================================
    * 실제 호출 로직
    *======================================================
    
    * ① 세팅할 값 목록 구성 (필요한 인덱스만 선택적으로)
    DATA lt_values TYPE tt_val_entry.
    lt_values = VALUE #(
      ( idx =   1  val = '1000'       )  " ko_001 = 회사코드
      ( idx =   2  val = '1000'       )  " ko_002 = 플랜트
      ( idx =   3  val = '20250101'   )  " ko_003 = 시작일
      ( idx =   4  val = '20251231'   )  " ko_004 = 종료일
      ( idx =   5  val = 'TA'         )  " ko_005 = 문서유형
      ( idx =  10  val = 'A'          )  " ko_010 = 상태코드
      ( idx =  20  val = '0000001234' )  " ko_020 = 고객번호
      ( idx = 100  val = 'X'          )  " ko_100 = 플래그
      * ... 필요한 것만 추가, 나머지는 INITIAL 유지
    ).
    
    * ② 구조체에 동적 매핑
    DATA(ls_param) = map_to_struct( it_values = lt_values ).
    
    * ③ JSON 직렬화 (1줄)
    * /ui2/cl_json 은 기본 소문자 키로 직렬화
    * → ko_001 필드 → JSON 키 "ko_001"
    DATA(lv_json) = /ui2/cl_json=>serialize(
      data        = ls_param
      pretty_name = /ui2/cl_json=>pretty_mode-none
    ).
    
    * 생성된 JSON 예시:
    * {"ko_001":"1000","ko_002":"1000","ko_003":"20250101",
    *  "ko_004":"20251231","ko_005":"TA","ko_006":"",
    *  ...,"ko_150":""}
    
    * ④ AMDP 호출 — string 1개만 전달
    DATA lt_result TYPE zcl_amdp_ko_param=>tt_result.
    
    zcl_amdp_ko_param=>execute(
      EXPORTING iv_json   = lv_json
      IMPORTING et_result = lt_result
    ).

    ⚠️ /ui2/cl_json=>serialize()는 INITIAL 필드도 JSON에 포함시킴 → "ko_006":"" 형태.

    ⚠️ SQLScript에서 JSON_VALUE()로 읽으면 공백 문자열 반환 → 조건 분기 시 COALESCE 또는 공백 체크 필요.

    4 AMDP 클래스 전체 코드

    클래스 정의

    CLASS zcl_amdp_ko_param DEFINITION
      PUBLIC FINAL
      CREATE PUBLIC.
    
      PUBLIC SECTION.
        INTERFACES if_amdp_marker_hdb.
    
        TYPES: BEGIN OF ty_result,
                 vbeln    TYPE vbeln_va,
                 kunnr    TYPE kunnr,
                 erdat    TYPE erdat,
                 category TYPE char10,
                 amount   TYPE dmbtr,
               END OF ty_result,
               tt_result TYPE STANDARD TABLE OF ty_result WITH DEFAULT KEY.
    
        CLASS-METHODS execute
          IMPORTING iv_json   TYPE string
          EXPORTING et_result TYPE tt_result
          RAISING   cx_amdp_error.
    
    ENDCLASS.

    클래스 구현 — SQLScript

    CLASS zcl_amdp_ko_param IMPLEMENTATION.
    
      METHOD execute
        BY DATABASE PROCEDURE
        FOR HDB
        LANGUAGE SQLSCRIPT
        USING vbak vbap.
    
        /*----------------------------------------------------------
          JSON 키 규칙:
            /ui2/cl_json 직렬화 → 소문자 필드명 그대로
            ko_001 필드 → JSON_VALUE(:iv_json, '$.ko_001')
            ko_002 필드 → JSON_VALUE(:iv_json, '$.ko_002')
            ...
    
          Constant Folding:
            :iv_json 은 파라미터(상수) → WHERE/CASE 어디서든
            JSON_VALUE() 직접 사용해도 파싱은 쿼리당 1회
        ----------------------------------------------------------*/
    
        et_result = SELECT
            h.vbeln,
            h.kunnr,
            h.erdat,
    
            -- ko_005(문서유형)로 카테고리 분류
            CASE
              WHEN h.auart = JSON_VALUE(:iv_json, '$.ko_005') THEN 'TYPE_A'
              WHEN h.auart = JSON_VALUE(:iv_json, '$.ko_010') THEN 'TYPE_B'
              ELSE 'OTHER'
            END AS category,
    
            COALESCE(i.netwr, 0) AS amount
    
          FROM vbak AS h
          INNER JOIN vbap AS i
            ON  i.mandt = h.mandt
            AND i.vbeln = h.vbeln
    
          WHERE h.mandt = SESSION_CONTEXT('CLIENT')
            -- ko_001 = 회사코드
            AND h.bukrs  = JSON_VALUE(:iv_json, '$.ko_001')
            -- ko_003, ko_004 = 날짜 범위
            AND h.erdat BETWEEN JSON_VALUE(:iv_json, '$.ko_003')
                            AND JSON_VALUE(:iv_json, '$.ko_004')
            -- ko_020 = 고객번호 (값이 있을 때만 필터)
            AND ( JSON_VALUE(:iv_json, '$.ko_020') = ''
                  OR h.kunnr = JSON_VALUE(:iv_json, '$.ko_020') )
    
          ORDER BY h.erdat DESC;
    
      ENDMETHOD.
    
    ENDCLASS.

    5 값이 없는 필드 — 선택적 필터 패턴

    💡 INITIAL(공백) 파라미터는 조건에서 자동 제외하는 패턴. 값이 있을 때만 필터 적용.

    WHERE h.mandt = SESSION_CONTEXT('CLIENT')
    
      -- 필수 조건 (항상 적용)
      AND h.bukrs = JSON_VALUE(:iv_json, '$.ko_001')
    
      -- 선택 조건 (값이 있을 때만 필터)
      AND ( JSON_VALUE(:iv_json, '$.ko_002') = ''      -- 공백이면 필터 Skip
            OR h.werks = JSON_VALUE(:iv_json, '$.ko_002') )
    
      AND ( JSON_VALUE(:iv_json, '$.ko_020') = ''
            OR h.kunnr = JSON_VALUE(:iv_json, '$.ko_020') )
    
      AND ( JSON_VALUE(:iv_json, '$.ko_005') = ''
            OR h.auart = JSON_VALUE(:iv_json, '$.ko_005') )

    핵심 요약

    단계핵심 코드포인트
    구조체 정의 ko_001 ~ ko_150 TYPE char50 char50 통일 → 동적 처리 단순화
    동적 매핑 ASSIGN COMPONENT lv_fname OF STRUCTURE 필드명을 |KO_{ idx WIDTH=3 FILL='0' }| 로 동적 생성
    JSON 직렬화 /ui2/cl_json=>serialize( data = ls_param ) 소문자 키 → $.ko_001 로 참조
    AMDP 호출 iv_json TYPE string 파라미터 1개로 150개 전달
    SQLScript JSON_VALUE(:iv_json, '$.ko_001') Constant Folding → WHERE/CASE 직접 사용 OK
    선택적 필터 JSON_VALUE(...) = '' OR field = JSON_VALUE(...) 공백 파라미터는 자동 Skip
    #AMDP #동적매핑 #FIELD-SYMBOLS #JSON파라미터 #ko_001 #JSON_VALUE #SQLScript #S4HANA #ABAP
Designed by Tistory.