728x90
  • 값을 변경하는 작업(UPDATE)을 할 때는 변경하기 전의 값을 바라봐도 상관없는 검색(SELECT)를 제외하고는 아무도 그 값에 접근할 수 없도록 해야 한다.

→ UPDATE 문은 이러한 이유로 자동으로 LOCK을 걸게 된다. 이 경우 **LOCK에 의한 대기(WAIT)**가 발생한다.

  • Dead Lock : 서로가 상대가 보유하고 있는 LOCK을 기다리느라 교착 상태 발생 

 

  • 예시)
  • Transaction A는 트랜잭션을 끝내기 위해 Accounts 를 변경하고 Orders를 변경해야 한다. (Order를 참조하여 회계전표를 생성하고 Order의 상태를 전기 상태로 바꾸기 위해)
  • Transaction B는 Orders를 작업하고 Accounts를 작업해야 한다.(Accounts에 전기된 오더를 취소하기 위해 Accounts 테이블을 변경해야 할 때)
  • 이 때, 마침 서로가 원하는 다음 데이터가 각각 상대방이 Lock을 걸고 있는 데이터일 때 Dead Lock이 발생하게 된다.
-- TRANSACTION A - ACCOUNTS의 NO = 1 ROW의 LOCK을 보유
UPDATE ACCOUNTS SET COL1 = 2 WHERE NO = 1
UPDATE ORDERS   SET COL1 = 2 WHERE NO = 2

-- TRANSACTION B - ORDERS의 NO = 2 ROW의 LOCK을 보유
UPDATE ORDERS   SET COL1 = 3 WHERE NO = 2
UPDATE ACCOUNTS SET COL1 = 3 WHERE NO = 1

→ DEAD LOCK이 발생하여 ORA-00060 에러코드 발생 → 오라클에 의해 한 쪽 ROLLBACK 후 처리

  • LATCH : SGA(메모리공간) 내부의 공유 데이터에 대한 배타적인 LOCK 보장
    • SGA에 접근하는 프로세스는 원하는 영역에 대한 LATCH를 획득해야 접근할 수 있다.

  • OS에 의한 선점 스케줄링(preemption) 발생 가능 (DEADLOCK 같은 것)

Latch Wait

728x90
728x90

  • 익스텐트는 ‘연속된’ 블록의 집합으로 익스텐트의 위치와 블록 개수로 관리를 하여 관리 정보를 줄이는 역할을 한다.(블록 개별로 관리하면 많아서)
  • 세그먼트는 익스텐트의 집합이다. 사용자(개발자)가 생성하는 테이블, 인덱스 등 이외에 undo 세그먼트, 정렬 세그먼트 등이 있다.

  • 데이터 파일 안에는 서로 다른 세그먼트들의 서로 다른 익스텐트들이 혼재해 있다. 즉 물리적으로 같은 세그먼트의 데이터들이 모여있는 것이 아니다.
  • 테이블 스페이스는 세그먼트를 분류하여 보관하기 위한 공간. 한 개 이상의 데이터 파일로 구성되어 있다.
  • 세그먼트는 ‘PCTFREE’와 ‘PCTUSED’ 파라미터를 사용하여 세그먼트 내의 빈 블록 공간을 점검하고 관리한다. 세그먼트 안에 공간이 부족하면 ‘익스텐트’를 추가하여 빈 블록을 늘린다.
  • ROWID : 데이터 행의 주소로, 데이터 파일 번호, 블록 번호, 행 번호 등의 정보로 구성되어 있다.
  • 테이블 스페이스가 가진 여유 공간이 부족할 때는 데이터 파일 확장 또는 데이터 파일 추가 작업을 해야 한다.

 

  • OS 블록과 Oracle 블록은 서로 매핑되어 있는 것이 아니다.
    • Oracle block은 오라클이 OS에게 요청하는 IO의 가장 작은 단위이다.
    • OS block은 OS의 read/write의 가장 작은 단위이다.
    • Oracle block 단위가 8kb 이고 OS block 단위가 4kb일 때, 오라클의 8kb 만큼의 데이터를 읽어오는 요청을 OS에게 보내면 OS는 8kb 만큼의 데이터 요청을 4kb로 각각 분해하여 동작할 것이다.

728x90
728x90

 

  • lsnrctl start : 기본 리스너 기동 명령어
  • listener.ora : 리스너 설정 파일
  • tnsnames.ora : Connection desripter, 커넥션에 필요한 정보가 담긴 파일 즉, 데이터베이스의 주소가 담긴 파일
  • sqlnet.ora : DCD(Dead connection detection) 기능, SDU 등을 사용하기 위한 파라미터들 설정 파일
    • *DCD : 검출 패킷을 클라이언트에게 보내 확인, 클라이언트의 데이터베이스와의 연결 해제 없이 갑작스러운 서버 다운 및 충돌로 인한 disconnet를 감지하기 위한 기능.
    • Session Data Unit (SDU) 설정 : 오라클 클라이언트와 서버 사이의 네트워크 통신에서 주고받는 데이터 단위 설정 

Connection Pool

  • 일반적으로 서버 프로세스를 생성하는 것은 무거운 작업이므로 적을수록 좋다.
  • 서버 프로세스를 미리 여러 개 생성해두고 client가 DB에 접근할 때 Pool에서 꺼내 사용하는 Connection Pool 등장

 

 

 

 

 

 

 

 

728x90
728x90

오라클의 4가지 상태

  • OPEN - 데이터를 처리할 수 있는 상태, 즉, SQL을 처리할 수 있는 상태
  • MOUNT - 데이터 파일 등에 접근할 수 있는 상태(컨트롤 파일을 읽은 상태)
  • NOMOUNT - 백그라운드 프로세스와 공유메모리가 존재하는 상태
  • SHUTDOWN - 정지 상태

 

  • SHUTDOWN → NOMOUNT 단계 : 파라미터를 읽어서 백그라운드 프로세스를 기동하고 공유 메모리 할당한다.
  • NOMOUNT → MOUNT 단계 : 컨트롤 파일을 읽는다.
  • MOUNT → OPEN 단계 : 데이터 파일, 리두 로그 파일 등을 확인한다.

오라클의 인스턴스

  • 인스턴스는 백그라운드 프로세스와 공유 메모리를 의미한다.
  • 즉, NOMOUNT 상태는 인스턴스가 기동한 상태이다.
  • 일반적으로 데이터베이스와 1대1 대응하지만 RAC(Real Application Clusters)를 사용하는 경우에는 1대1 대응이 아니다.

인스턴스를 표시한 oracle의 대략적인 구조

  • 서버 프로세스는 인스턴스에 포함되지 않는 사용자(Client)와의 연결을 지원하기 위한 별도의 프로세스.
  • 서버 프로세스는 Dedicated Server Process와 Shared Server Process 두 가지 형태로 나뉜다.
    • Dedicated Server Process : 특정 클라이언트를 전담하는 서버 프로세스
    • Shared Server Process : Dispatcher가 요청을 수신하여 Request Queue에 담으면 그것을 처리하는 서버 프로세스

 

728x90
728x90

https://namu.wiki/w/TLS#toc

 

https://www.youtube.com/watch?v=hHnEaQB-3C4&ab_channel=SAPBASIS

 

 

 

 

728x90
728x90

Report Program?

- 데이터베이스에서 원하는 데이터를 추출하여 원하는 형태로 가공하여 리포트 형식으로 조회하는 프로그램

- Type-1 Program이나 Executable Program이라고 한다.

- 아래 그림의 흐름대로 프로그램이 처리된다.

Executable Program (Report Program) Flow

Report Program의 흐름

1. runtime environment가 INITIALIZATION 이벤트를 생성하고 이에 대응하면 이벤트 블럭(소스코드에서 INITIALIZATION  구문 영역)을 호출한다. 보통 선언된 변수들을 날짜에 맞게 초기화하는 등의 작업을 한다.

2. selection screen이 정의되어 있다면  control(SAP GUI)은 selection screen processor를 반환한다. 이 processor는 이에 대응하는 이벤트 블럭인 AT-SELECTION SCREEN 구문을 호출한다. 사용자에게 조회 조건 입력하는 화면을 출력하여 보여준다.

3. control은 reporting processor로 넘어간다. 이 processor는 START-OF-SELECTION 이벤트를 생성하고 이에 대응하는 이벤트 블럭(START-OF-SELECTION)을 호출한다.

4. Logical Database를 사용한다면 이벤트 블럭을 여기서 더 호출하게 된다.(LDB : 사용 빈도가 높은 테이블의 데이터를 조회하기 위해서 JOIN이 자주 사용되고 조회 조건이 유사한 경우를 하나의 패키지로 생성하여 재사용)

5. reporting processor는 END-OF-SELECTION 이벤트를 호출하고 대응하는 이벤트 블럭을 호출한다.

6. List 관련 소스코드가 있다면 control은 List Processor로 넘어간다. 이 Processor는 ABAP 프로그램에 정의된 리스트르를 출력한다. List Processor는 리스트에 대한 유저 action을 토대로 각 이벤트를 호출하여 실행한다. 

7. selection screen이 선언부에 있으면 같은 프로그램이 종료되면 자동적으로 호출된다.(Shift+F3으로 종료하면 다시 조회 조건 입력화면에서부터 다시 시작한다는 뜻인 듯)

 

 

프로그램 구조

- Report program은 다음과 같이 크게 3가지 구조로 분류할 수 있다.

1. 데이터 선언부와 조회 선택 화면(SELECTION SCREEN)

2. 실행 시점까지의 Event

3. 데이터를 뿌려주는 List Event

 

 

1. 데이터 선언부와 조회 선택 화면

*&---------------------------------------------------------------------*
*& REPORT  ZBCR0040
*&
*&---------------------------------------------------------------------*
*&라이센스 관리를 위한 유저 현황 리포트
*&
*&---------------------------------------------------------------------*

REPORT ZBCR0040.

TYPE-POOLS: icon. " TYPE-GROUP을 사용하기 위해 선언

" SALV 사용을 위한 관련 타입 변수 선언
DATA : ALV_TABLE TYPE REF TO CL_SALV_TABLE.
DATA : ALV_COLUMNS TYPE REF TO CL_SALV_COLUMNS_TABLE.
DATA : SINGLE_COLUMN TYPE REF TO CL_SALV_COLUMN.

" 개별 계정 현황 집계 테이블
TYPES : BEGIN OF T_INDI_USER,

          BNAME        LIKE USER_ADDR-BNAME,      " SAP아이디
          BNAME_NM     LIKE USER_ADDR-NAME_TEXTC, " 사용자이름
          KOSTL        LIKE CSKT-KOSTL,           " 코스트센터
          KOSTL_NM     LIKE CSKT-KTEXT,           " 코스트센터 내역
          LIC_TYPE     LIKE USR06-LIC_TYPE,       " 라이센스
          LIC_TYPE_NM  LIKE TUTYP-UTYPTEXT,       " 라이센스 내역
          UFLAG        LIKE USR02-UFLAG,          " 잠금생타값
          UFLAG_NM     TYPE ICON_D,               " 잠금상태아이콘
          TRDAT        LIKE USR02-TRDAT,          " 마지막 로그온 일자
          GLTGB        LIKE USR02-GLTGB,          " 효력종료일

  END OF T_INDI_USER.

DATA : GT_INDI_USER TYPE TABLE OF T_INDI_USER.
DATA : GS_INDI_USER LIKE LINE OF GT_INDI_USER.

" 코스트 센터별 현황
TYPES : BEGIN OF T_KOSTL_USER,
          BUKRS        LIKE CSKS-BUKRS, " 회사
          BUTXT        LIKE T001-BUTXT, " 회사명
          KOSTL        LIKE CSKS-KOSTL, " 코스트센터
          KOSTL_NM     LIKE CSKT-KTEXT, " 코스트센터명
          TOTAL_CNT    TYPE I,          " 발급 계정 수
          LOCKED_CNT   TYPE I,          " 잠긴 계정 수
          OPEN_CNT     TYPE I,          " 열린 계정 수
  END OF T_KOSTL_USER.


DATA : GT_KOSTL_USER TYPE TABLE OF T_KOSTL_USER.
DATA : GS_KOSTL_USER LIKE LINE OF GT_KOSTL_USER.

" 회사코드별 현황
TYPES : BEGIN OF T_BUKRS_USER,
          BUKRS        LIKE CSKS-BUKRS, " 회사
          BUTXT        LIKE T001-BUTXT, " 회사명
          TOTAL_CNT    TYPE I,          " 발급 계정 수
          LOCKED_CNT   TYPE I,          " 잠긴 계정 수
          OPEN_CNT     TYPE I,          " 열린 계정 수
  END OF T_BUKRS_USER.

DATA : GT_BUKRS_USER TYPE TABLE OF T_BUKRS_USER.
DATA : GS_BUKRS_USER LIKE LINE OF GT_BUKRS_USER.

" 라이센스별 현황
TYPES : BEGIN OF T_LIC_USER,

          LIC_TYPE     LIKE USR06-LIC_TYPE,  " 라이센스
          LIC_TYPE_NM  LIKE TUTYP-UTYPTEXT,  " 라이센스 내역
          TOTAL_CNT    TYPE I,               " 발급 계정 수
          LOCKED_CNT   TYPE I,               " 잠긴 계정 수
          OPEN_CNT     TYPE I,               " 열린 계정 수

  END OF T_LIC_USER.

DATA : GT_LIC_USER TYPE TABLE OF T_LIC_USER.
DATA : GS_LIC_USER  LIKE LINE OF GT_LIC_USER.


" 리포트 프로그램에서 SELECTION SCREEN은 프로그래머가 직접 정의하지 않아도
" 자동으로 스크린을 생성하고 FLOW LOGIC을 구현하도록 도와준다.
SELECTION-SCREEN BEGIN OF BLOCK BLOCK1 WITH FRAME TITLE TEXT-001.
SELECTION-SCREEN BEGIN OF LINE.

" PARAMETERS는 사용자가 값을 입력하도록 INPUT 필드를 정의한다.
" 통계 종류 라디오 버튼
PARAMETERS : P_RADI_1 RADIOBUTTON GROUP RADI USER-COMMAND UCOM1  DEFAULT 'X'. " 파라미터 선언
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_1.  " PARAMETERS와 SELECT-OPTIONS의 내역을 나타내기 위한 selection text
PARAMETERS : P_RADI_2 RADIOBUTTON GROUP RADI.
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_2.
PARAMETERS : P_RADI_3 RADIOBUTTON GROUP RADI.
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_3.
PARAMETERS : P_RADI_4 RADIOBUTTON GROUP RADI.
SELECTION-SCREEN COMMENT (15) FOR FIELD P_RADI_4.


SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK BLOCK1.


SELECTION-SCREEN BEGIN OF BLOCK BLOCK2 WITH FRAME TITLE TEXT-002. " 선택 블럭의 제목을 적기 위한 텍스트 심볼 선언
SELECTION-SCREEN BEGIN OF LINE.

SELECTION-SCREEN COMMENT (12) FOR FIELD S_TRDAT MODIF ID ID1. " MODIF ID를 부여하여 조회 조건을 그룹화 할 수 있다.

" SELECT-OPTIONS는 2개의 INPUT 필드를 통해 다양한 조건 값을 입력받을 수 있다.
" RANGE변수와 같은 구조(인터널 테이블)를 가지고 있다.
SELECT-OPTIONS : S_TRDAT FOR GS_INDI_USER-TRDAT MODIF ID ID1.

SELECTION-SCREEN END OF LINE.

SELECTION-SCREEN END OF BLOCK BLOCK2.


" 이벤트 중 프로그램을 실행했을 때 가장 먼저 수행되는 이벤트
" SELECTION-SCREEN이 조회되기 전에 작동하므로 변수에 초기값을 지정할 때 사용
INITIALIZATION.
  S_TRDAT-SIGN = 'I'.
  S_TRDAT-OPTION = 'BT'.
  S_TRDAT-HIGH = SY-DATUM.

  S_TRDAT-LOW = SY-DATUM - 50.

  APPEND S_TRDAT.

" SELECTION-SCREEN OUTPUT은 사용자가 버튼을 클릭했을 때 작동
" SCREEN은 STRUCTURE이며 LOOP AT SCREEN을 수행할 때 스크린 필드의 MODIF ID가져옴 
" MODIF ID를 통해 스크린 필드 제어
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.

    IF P_RADI_1 EQ 'X' AND SCREEN-GROUP1 EQ 'ID1'.
      SCREEN-ACTIVE = '1'.
      MODIFY SCREEN.

    ELSEIF P_RADI_1 NE 'X' AND SCREEN-GROUP1 EQ 'ID1'.
      SCREEN-ACTIVE = '0'. " 그룹화한 MODIF ID로 묶인 필드들을 활성화/비활성화
      MODIFY SCREEN.
    ENDIF.

  ENDLOOP.

 

 

2. 실행 시점까지의 Event

START-OF-SELECTION. " 데이터베이스에서 원하는 데이터를 가져오는 작업 수행

    SELECT A~BNAME      AS BNAME
           B~NAME_TEXTC AS BNAME_NM
           B~KOSTL      AS KOSTL
           C~LIC_TYPE   AS LIC_TYPE
       "    D~UTYPTEXT   AS LIC_TYPE_NM
           A~TRDAT      AS TRDAT
           A~GLTGB      AS GLTGB
           A~UFLAG      AS UFLAG
 
      INTO CORRESPONDING FIELDS OF TABLE GT_INDI_USER
      FROM USR02 AS A
     LEFT OUTER JOIN USER_ADDR AS B
        ON A~BNAME EQ B~BNAME
     LEFT OUTER JOIN USR06 AS C
        ON A~BNAME EQ C~BNAME
     WHERE A~TRDAT IN S_TRDAT
      .
 
 
 
    DATA : LV_KTEXT LIKE CSKT-KTEXT.
 
    LOOP AT GT_INDI_USER INTO GS_INDI_USER.
 
      SELECT SINGLE UTYPTEXT
        INTO GS_INDI_USER-LIC_TYPE_NM
        FROM TUTYP AS A
       WHERE A~USERTYP EQ GS_INDI_USER-LIC_TYPE
         AND A~LANGU EQ '3'
        .
 
      IF GS_INDI_USER-UFLAG IS INITIAL OR GS_INDI_USER-UFLAG EQ 0.
        GS_INDI_USER-UFLAG_NM = ICON_UNLOCKED.
      ELSE.
        GS_INDI_USER-UFLAG_NM = ICON_LOCKED.
      ENDIF.
 
 
      CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
        EXPORTING
          INPUT  = GS_INDI_USER-KOSTL
        IMPORTING
          OUTPUT = GS_INDI_USER-KOSTL.
 
      SELECT SINGLE KTEXT
        FROM CSKT
        INTO LV_KTEXT
       WHERE KOSTL EQ GS_INDI_USER-KOSTL
         AND SPRAS EQ '3'
         AND DATBI GT SY-DATUM.
 
      IF SY-SUBRC = 0.
        GS_INDI_USER-KOSTL_NM = LV_KTEXT.
 
      ENDIF.
 
      MODIFY GT_INDI_USER FROM GS_INDI_USER.
      CLEAR LV_KTEXT.
    ENDLOOP.
 
    
 

 

3.1 데이터를 뿌려주는 List Event(여기서는 SALV)

END-OF-SELECTION. "  실행 환경에서 호출되는 마지막 이벤트. 데이터를 화면에 뿌려준다.  

  PERFORM DISPLAY_SETTINGS_1 USING GT_INDI_USER.  "  DISPLAY하기 위한 세팅

  PERFORM DISPLAY_ALV_REPORT.
 
 
FORM DISPLAY_SETTINGS_1 CHANGING PT.
    DATA : ERR_MESSAGE TYPE REF TO CX_SALV_MSG.
 
    TRY.
        CL_SALV_TABLE=>FACTORY(
        IMPORTING
          R_SALV_TABLE = ALV_TABLE
          CHANGING
            T_TABLE = PT ).
 
 
        ALV_COLUMNS = ALV_TABLE->GET_COLUMNS( ).
        ALV_COLUMNS->SET_OPTIMIZE( 'X' ).
        " ALV_COLUMNS->SET_COLOR_COLUMN( 'LINE_COLOR' ).
 
        PERFORM BUILD_LAYOUT.
 
        IF P_RADI_1 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_1. " 필드 카탈로그 세팅
        ELSEIF P_RADI_2 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_2.
        ELSEIF P_RADI_3 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_3.
        ELSEIF P_RADI_4 EQ 'X'.
          PERFORM BUILD_FIELDCATALOG_4.
        ENDIF.
 
        PERFORM BUILD_TOOLBAR. " 툴바 세팅
        PERFORM HIDE_COLUMNS.  " 숨길 컬럼 세팅
        PERFORM REPORT_SETTINGS. 
 
      CATCH CX_SALV_MSG INTO ERR_MESSAGE.
    ENDTRY.
 
  ENDFORM.
 
  FORM BUILD_LAYOUT.
    DATA : LAYOUT TYPE REF TO CL_SALV_LAYOUT.
    DATA : LAYOUT_KEY TYPE SALV_S_LAYOUT_KEY.
 
    LAYOUT = ALV_TABLE->GET_LAYOUT( ).
 
    LAYOUT_KEY-REPORT = SY-REPID.
    LAYOUT->SET_KEY( LAYOUT_KEY ).
 
    LAYOUT->SET_SAVE_RESTRICTION( IF_SALV_C_LAYOUT=>RESTRICT_NONE ).
 
  ENDFORM.
 
  FORM BUILD_FIELDCATALOG_1.
    DATA : ERR_NOTFOUND TYPE REF TO CX_SALV_NOT_FOUND.
 
    TRY.
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'BNAME' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '사용자' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '사용자' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '사용자' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 10 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'BNAME_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '사용자명' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '사용자명' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '사용자명' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 25 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'KOSTL_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '코스트센터명' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '코스트센터명' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '코스트센터명' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 25 ).
 
 
        SINGLE_COLUMN ?= ALV_COLUMNS->GET_COLUMN( 'LIC_TYPE' ).
        SINGLE_COLUMN->set_SIGN( ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '라이센스' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '라이센스' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '라이센스' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 8 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'LIC_TYPE_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '라이센스명' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '라이센스명' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '라이센스명' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 20 ).
 
        SINGLE_COLUMN = ALV_COLUMNS->GET_COLUMN( 'UFLAG_NM' ).
        SINGLE_COLUMN->SET_SHORT_TEXT( '잠금상태' ).
        SINGLE_COLUMN->SET_MEDIUM_TEXT( '잠긍상태' ).
        SINGLE_COLUMN->SET_LONG_TEXT( '잠금상태' ).
        SINGLE_COLUMN->SET_OUTPUT_LENGTH( 8 ).
 
      CATCH CX_SALV_NOT_FOUND INTO ERR_NOTFOUND.
    ENDTRY.
 
  ENDFORM.
 
 
FORM BUILD_TOOLBAR.

    DATA : TOOLBAR_FUNCTIONS TYPE REF TO CL_SALV_FUNCTIONS_LIST.
 
    TOOLBAR_FUNCTIONS = ALV_TABLE->GET_FUNCTIONS( ).
    TOOLBAR_FUNCTIONS->SET_ALL( ).
 
  ENDFORM.
 
  FORM HIDE_COLUMNS.
 
 
 
  ENDFORM.
 
  FORM REPORT_SETTINGS.
    DATA : REPORT_SETTINGS TYPE REF TO CL_SALV_DISPLAY_SETTINGS.
 
    REPORT_SETTINGS = ALV_TABLE->GET_DISPLAY_SETTINGS( ).
    REPORT_SETTINGS->SET_STRIPED_PATTERN( IF_SALV_C_BOOL_SAP=>TRUE ).
 
 
    IF P_RADI_1 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '사용자 통계' ).
    ELSEIF P_RADI_2 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '코스트 센터별 통계' ).
 
    ELSEIF P_RADI_3 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '회사코드별 통계' ).
    ELSEIF P_RADI_4 EQ 'X'.
      REPORT_SETTINGS->SET_LIST_HEADER( '라이센스별 통계' ).
    ENDIF.
 
 
 
  ENDFORM.
 
 
  FORM DISPLAY_ALV_REPORT.
 
    IF P_RADI_1 NE 'X'.
 
      ALV_TABLE->get_aggregations( )->add_aggregation( 'TOTAL_CNT' ).
      ALV_TABLE->get_aggregations( )->add_aggregation( 'LOCKED_CNT' ).
      ALV_TABLE->get_aggregations( )->add_aggregation( 'OPEN_CNT' ).
 
    ENDIF.
 
    ALV_TABLE->DISPLAY( ).
  ENDFORM.
 

 

 

3.2 EASY ABAP의 List Process 이벤트 설명

728x90
728x90

FIELD SYMBOL이란?

- 특정 데이터 오브젝트를 가리킬 수 있는 포인터

 

FIELD SYMBOL의 특징

- ABAP 프로그램 내에서 변수에 동적인 접근 가능

- 자기 자신을 위한 메모리 공간 점유 하지 않음

- 데이터 이름과 속성은 실행 시점(RUNTIME)에 결정

- 모든 데이터 오브젝트에 지정 가능

- 일단 필드 심볼이 할당되면 데이터 오브젝트와 필드 심볼 간에는 차이가 없다(필드 심볼 변경이 곧 데이터 오브젝트 변경)

- MOVE와 같은 ABAP 명령어 사용 가능

- 필드 심볼은 타입을 명시 혹은 명시하지 않고도 생성할 수 있다. 타입이 명시되지 않으면 할당되는 오브젝트의 타입을 그대로 상속받는다.

 

FIELD SYMBOL 메커니즘(그림)

- 필드 심볼에 할당되면 같은 메모리 주소를 할당받기 때문에 필드 심볼이 곧 해당 데이터 오브젝트를 가리키는 변수가 된다.

- 즉 필드 심볼을 이용하여 변수값을 변경하는 것과 기존 변수명을 이용하여 변수값을 변경하는 것은 차이가 없다.

- ASSIGN을 만나면 아무 것도 가리키고 있지 않은 필드 심볼이라는 포인터가 특정 데이터 오브젝트를 가리키는 포인터가 된다.

 

DATA : BEGIN OF LINE,
    COL1(12) VALUE '1234567890AB',
END OF LINE.

FIELD-SYMBOLS : <FS>.

ASSIGN LINE-COL1+6(*) TO <FS>.
WRITE : / <FS>.

결과 : 7890AB

 

필드 심볼 선언

1. Generic Type Field Symbol

- 필드 심볼을 선언할 때 타입을 지정하지 않고, 할당되는 데이터 오브젝트 유형에 따라 속성을 상속받는다.

FIELD-SYMBOLS : <FS1>.
FIELD-SYMBOLS : <FS2> TYPE ANY.
FIELD-SYMBOLS : <FS2> TYPE ANY TABLE.

- TYPE ANY TABLE을 쓰려면 할당할 데이터 오브젝트가 인터널 테이블이어야 한다.

- TABLE 키워드가 없으면 LINE타입의 구조체로 활용할 수 있다.

 

2. Fully Type Field Symbol

- 필드 심볼을 정의할 때 타입이 정해진 형태로 선언

- 같은 속성의 데이터 오브젝트를 할당받아야 한다.

FIELD-SYMBOLS : <FS1> TYPE GT_TAB.
FIELD-SYMBOLS : <FS2> LIKE LINE OF GT_TAB.
FIELD-SYMBOLS : <FS3> LIKE GT_TAB.

- GT_TAB이 헤더라인이 있는 인터널 테이블이라면 3개의 필드 심볼은 차이가 없다.

 

LIKE와 LIKE LINE OF의 차이점

- GT_TAB이 HEADER LINE이 있느냐 없느냐에 따라 차이가 발생한다. HEADER LINE이 없다면 <FS3>은 인터널 테이블을 가리키는 필드 심볼을 선언하게 된다. 헷갈리므로 LIKE 구문은 자제하는 게 좋다.

 

 

 

ASSIGN 구문 동적 사용

" 구조체 선언
DATA : BEGIN OF GS_STR,
  COL1 TYPE CHAR5  VALUE 'KOREA',
  COL2 TYPE CHAR10 VALUE 'SEOUL',
  COL3 TYPE CHAR15 VALUE 'TWIN BUILDDING',
END OF GS_STR.

" 필드명을 담을 변수 선언
DATA : GV_FNAME TYPE C LENGTH 10.
DATA : GV_IDX   TYPE N.

FIELD-SYMBOLS : <FS1> LIKE GS_STR. " 구조체 가리킬 필드 심볼
FIELD-SYMBOLS : <FS2> TYPE ANY.    " 구조체의 각 필드를 가리킬 필드 심볼

ASSIGN GS_STR TO <FS1>. " 구조체 할당

DO 3 TIMES.

  CLEAR : GV_FNAME.
  GV_IDX = SY-INDEX.
  GV_FNAME = 'COL'.
  CONCATENATE GV_FNAME GV_IDX INTO GV_FNAME. " 필드명 동적 생성

  ASSIGN COMPONENT GV_FNAME OF STRUCTURE <FS1> TO <FS2>. " 구조체 <FS1>의 필드를 변수를 통해 지정하여 <FS2>에 할당
  WRITE : / <FS2>.

ENDDO.

 

필드 심볼과 CASTING(형변환)

- 데이터 오브젝트를 필드 심볼에 ASSIGN 할 경우에, CASTING(형변환)를 이용해 모든 데이터 타입을 필드 심볼에 할당할 수 있다.

- 암묵적 형변환과 명시적 형변환 2가지가 있다.

 

1. 암묵적 형변환(Implicit Casting)

- 타입이 정해진 필드 심볼과 데이터 오브젝트 타입이 서로 다른 경우 CASTING 키워드를 이용하여 ASSIGN 해야 한다.

ASSIGN GV_ADDR TO <FS> CASTING.

 

2. 명시적 형변환(Explicit Casting)

- 필드 심볼을 Generic Type으로 선언한 경우 Casting 시 TYPE을 지정하여 ASSIGN 해야 한다.

FIELD-SYMBOLS : <FS1> TYPE ANY.
ASSIGN ADDR TO <FS1> CASTING TYPE T_ADDR.

 

필드 심볼과 인터널 테이블

- 필드 심볼을 이용하여 인터널 테이블을 변경하게 되면 Work Area로 복사하는 과정이 생략되어 성능이 향상된다.

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CONNID TYPE SFLIGHT-CONNID,
  CARRNAME TYPE SCARR-CARRNAME,
END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE.
FIELD-SYMBOLS : <FS> LIKE GS_LINE.

SELECT CARRID CONNID
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.

LOOP AT GT_ITAB ASSIGNING <FS>.

  SELECT SINGLE CARRNAME INTO <FS>-CARRNAME
    FROM SCARR WHERE CARRID = <FS>-CARRID.

  WRITE : / <FS>.
ENDLOOP.

 

 

DATA : BEGIN OF GS_LINE,
  CARRID TYPE SFLIGHT-CARRID,
  CONNID TYPE SFLIGHT-CONNID,
  CARRNAME TYPE SCARR-CARRNAME,
END OF GS_LINE.

DATA : GT_ITAB LIKE TABLE OF GS_LINE.
FIELD-SYMBOLS : <FS> LIKE GS_LINE.

SELECT CARRID CONNID
  INTO CORRESPONDING FIELDS OF TABLE GT_ITAB
  FROM SFLIGHT.

LOOP AT GT_ITAB ASSIGNING <FS>. " 필드 심볼에 할당

  SELECT SINGLE CARRNAME INTO <FS>-CARRNAME
    FROM SCARR WHERE CARRID = <FS>-CARRID.
 
  " 인터널테이블에 그대로 넣고 MODIFY 구문 없이도 인터널 테이블 변경됨
  " EX) MODIFY GT_ITAB FROM GS_ITAB <= 이런 구문 없어도 인터널 테이블 변경됨.
 
  WRITE : / <FS>.
ENDLOOP.

필드 심볼의 경우 WORK AREA를 거치지 않는다 = 메모리에 저장된 값을 바로 변경한다.

 

필드 심볼 활용

DATA : GS_COSP TYPE COSP. " 월별 데이터가 있는 구조체 선언

GS_COSP-WTG001 = 100.
GS_COSP-WTG002 = 200.
GS_COSP-WTG003 = 300.
GS_COSP-WTG004 = 400.
GS_COSP-WTG005 = 500.
GS_COSP-WTG006 = 600.
GS_COSP-WTG007 = 700.
GS_COSP-WTG008 = 800.
GS_COSP-WTG009 = 900.
GS_COSP-WTG010 = 1000.
GS_COSP-WTG011 = 1100.
GS_COSP-WTG012 = 1200.

DATA : FNAME(14). " 필드명을 담을 변수 선언
DATA : SUM LIKE COSP-WTG001. " 합계 금액을 담을 변수 선언

DATA : CC(2) TYPE N. " 필드명 변수 만드는 데 쓰일 변수 선언
DO 12 TIMES.
  CC = SY-INDEX. " 01, 02, 03 ...
  CONCATENATE 'GS_COSP-WTG0' CC INTO FNAME. " WTG001, WTG002, WTG003 ...

  ASSIGN (FNAME) TO <FS>.
  SUM = SUM + <FS>.
  CLEAR : FNAME, <FS>.

  WRITE : / SUM.

ENDDO.

- 위처럼 테이블 구조가 1월 2월 3월 ~ 12월 등 필드가 연속된 날짜 등으로 구분되어 있는 경우

- 필드 심볼을 이용하여 필드명을 동적으로 조작해서 ROW가 아닌 COLUMN을 DO같은 반복문을 이용해 조작할 수가 있다.

 

 

데이터 참조

- 데이터 참조는 데이터 오브젝트에 대한 포인터이다.

- 필드 심볼은 포인터만 가지고 있으며 ASSIGN된 데이터 오브젝트의 메모리에서 작업하지만 데이터 참조는 포인터를 값으로 가지는 참조 변수이며 자신의 메모리 영역을 갖는다.

PARAMETERS : P_TNAME(30) DEFAULT 'SFLIGHT'.

DATA : DREF TYPE REF TO DATA.

FIELD-SYMBOLS : <FS1> TYPE ANY.
FIELD-SYMBOLS : <FS2> TYPE ANY.

CREATE DATA DREF TYPE (P_TNAME). " 데이터 오브젝트 자체를 프로그램 실행 도중 동적으로 생성

ASSIGN DREF->* TO <FS1>.

SELECT *
  FROM (P_TNAME) INTO <FS1> UP TO 3 ROWS.

DO.
  ASSIGN COMPONENT SY-INDEX OF STRUCTURE <FS1> TO <FS2>.
  IF SY-SUBRC NE 0.
    SKIP.
    EXIT.
  ENDIF.

  WRITE : <FS2>.
ENDDO.

ENDSELECT.

- 필드 심볼은 데이터 오브젝트에 담겨 있는 메모리 저장소에 작업을 한다. 필드 심볼은 데이터 오브젝트의 또 다른 상징적인 이름일 뿐이다.

- 데이터 참조(Reference Variable)는 데이터 오브젝트를 가리키는 포인터이며 필드 심볼을 통해 데이터 오브젝트의 값에 접근한다ㅐ. 

- 프로그램 실행 시점에 데이터 오브젝트는 동적으로 생성되기 때문에 메모리 주소도 동적으로 할당된다.

- 이것이 필드 심볼을 이용하여 데이터 오브젝트에 접근하게 되는 이유이다.

 

PARAMETERS : P_TNAME(30) DEFAULT 'SFLIGHT'.

DATA : DREF TYPE REF TO DATA.

FIELD-SYMBOLS : <FS1> TYPE ANY.
FIELD-SYMBOLS : <FS2> TYPE ANY.

CREATE DATA DREF TYPE (P_TNAME). " 데이터 오브젝트 자체를 프로그램 실행 도중 동적으로 생성, 참조 변수가 데이터 오브젝트의 주소값을 가지게 됨.

ASSIGN DREF->* TO <FS1>. " 동적으로 생성된 데이터 오브젝트의 값에 접근할 때 필드 심볼을 이용하기 위해 필드 심볼에 assign(dereference)
" dereference : 주소를 통해 값에 접근하는 것
" DREF는 참조 변수고 메모리 주소를 값으로 가질 뿐 데이터 오브젝트 그 자체는 아니다.
" DREF가 가리키는 메모리 주소를 FS1에게 할당하여 FS1이 데이터 오브젝트를 가리키게 하는 것이 Dereference이다.  
SELECT *
  FROM (P_TNAME) INTO <FS1> UP TO 3 ROWS.

DO.
  ASSIGN COMPONENT SY-INDEX OF STRUCTURE <FS1> TO <FS2>.
  IF SY-SUBRC NE 0.
    SKIP.
    EXIT.
  ENDIF.

  WRITE : <FS2>.
ENDDO.

ENDSELECT.

- DREF가 가리키는 데이터 오브젝트는 메모리 주소이며 FS1에게 이 메모리 주소를 할당하여 FS1이 메모리 주소를 통해 동적으로 생성한 데이터 오브젝트에게 접근하도록 유도한다.

 

- 테이블명 등을 파라미터로 받아와서 사용하는 경우에는 미리 어떤 테이블의 구조체나 인터널 테이블에 맞는 데이터 오브젝트를 생성해 놓을 수 없으므로 동적으로 생성해 그 데이터 오브젝트의 메모리 주소를 data reference에 담아두고 Field Symbol에 할당하여 활용한다.  

 

TYPES : BEGIN OF T_STRUCT,
  COL1 TYPE CHAR15,
  COL2 TYPE CHAR15,
END OF T_STRUCT.

DATA : DREF1 TYPE REF TO DATA. " 참조변수 선언
DATA : DREF2 TYPE REF TO DATA.

FIELD-SYMBOLS : <FS1> TYPE T_STRUCT.
FIELD-SYMBOLS : <FS2> TYPE CHAR15.

CREATE DATA DREF1 TYPE T_STRUCT. " 데이터 오브젝트 생성하고 그 주소값을 참조 변수에 대입

ASSIGN DREF1->* TO <FS1>. " DREF1이 가리키는 메모리 주소로 가서 데이터 오브젝트를 가리키도록 FS1에게 할당

<FS1>-COL1 = 'ENJOY ABAP'.
<FS1>-COL2 = 'ABAP PROGRAMMING'.

DREF2 = DREF1.

ASSIGN DREF2->* TO <FS2> CASTING.
WRITE / <FS2>.

GET REFERENCE OF <FS1>-COL2 INTO DREF2. " 이미 생성된 데이터 오브젝트를 참고하여 참조 변수 생성

ASSIGN DREF2->* TO <FS2>.
WRITE / <FS2>.

 

728x90

'OLD' 카테고리의 다른 글

(작업중)SSL이란 (with SAP)  (1) 2024.06.11
(작업중)EASY ABAP - 11. Report Program (With ALV)  (0) 2024.06.10
(작업중)Java의 Servlets과 Servlet Containers  (1) 2024.05.13
개인 프로젝트 진행 상황  (0) 2024.05.13
PP 공부  (0) 2024.05.09
728x90

https://www.baeldung.com/java-servlets-containers-intro

https://velog.io/@sudong/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91%EC%9E%90%EB%B0%94-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80%EC%9A%94

https://stackoverflow.com/questions/7151206/definition-of-a-java-container

 

 

728x90

+ Recent posts