본문 바로가기

SAP&ABAP

EASY ABAP - 5. SQL

728x90

SAP ABAP 에서의 SQL은 OPEN SQL과 NATIVE SQL 2가지로 나뉜다.

- OPEN SQL은 ABAP에서 사용되는 개념이며 Database Interface를 통해 결국은 Native SQL로 번역된다.

- Native SQL은 일반적으로 데이터베이스에 사용되는 SQL을 의미한다.

2가지 SQL의 처리 흐름 비교

- 보통 OPEN SQL로 해결 되지 않는 복잡한 SQL은 NATIVE SQL을 이용한다. 각 DB벤더에서 제공하는 기본적인 함수 등을 사용할 수 있다. ( +기호로 조인 및 LPAD 등 )

- Local Buffer : 데이터베이스의 부하를 줄이는 기술. DB에도 buffer가 있지만 Database와 통신하기 전에도 해당 작업을 하는 단계가 또 있는듯함.

- OPEN SQL은 클라이언트 종속적이라 MANDT 필드를 조건에 넣지 않아도 되지만 Native SQL을 쓸 떄에는 MANDT 필드를 넣어주어야 한다.

- SQL 수행결과가 성공이면 SY-SUBRC = 0, SY-DBCNT는 ROW의 수를 반환한다.

- OPEN SQL의 MODIFY는 INSERT와 UPDATE의 기능을 수행한다. 키값을 기준으로 UPDATE할 지 INSERT할 지 정한다.

 

OPEN SQL : 데이터 읽기

SELECT

INTO

FROM

WHERE

GORUP BY

HAVING

ORDER BY

- 위와 같은 키워드가 있고 대부분 일반적인 SQL과 비슷함 

 

SELECT 

- SELECT SINGLE 옵션은 조회된 ROW중 임의의 ROW를 하나 반환한다. 따라서 WHERE 조건을 제대로 입력하여 하나의 ROW만 반환하도록 SQL을 잘 짜야 한다.

 

INTO 

- 조회한 결과를 변수에 저장하는 기능을 수행한다.

- CORRESPODING FIELDS OF 구문을 사용하면 동일 필드명에 값을 할당한다.

- SAP의 테이블들은 컬럼이 상당히 많기 때문에 SELECT 문에서 *을 삼가는 것이 좋다. fetch size를 줄여야 성능이 향상되기 때문이다.

- 구조체(Work Area) : 한 라인만 조회하고자 할 경우 Work Area(변수, 구조체)에 값을 할당한다.

- Internal Table : 여러 라인을 조회하고자 하는 경우 사용한다. APPENDING은 인터널 테이블에 추가로 INSERT하고 INTO는 인터널 테이블의 데이터를 삭제한 다음 INSERT한다.

 

FROM

- CLIENT SPECIFIED : 자동 클라이언트 설정 해제

- BYPASSING BUFFER : SAP Local Buffer에서 값을 읽지 않는다. 테이블이 Buffering이 설정되어 있어도 무시하고 데이터베이스에서 직접 데이터를 읽어 온다. 사용하는 이유는 가장 최신 정보를 가져오기 위해서 또는 자주 사용하지 않는 데이터를 local buffer에 남겨두지 않게 하여 메모리 사용을 줄여 효율성을 높이기 위함.

- UP TO n ROWS : SELECT 개수 조절. 

 

 

JOIN

- ANSI 표준은 INNER, OUTER JOIN ~ ON을 사용한다.

- ABAP에서는 조인보다는 조회 후 인터널 테이블에 각각 저장하여 기준이 되는 테이블을 LOOP를 돌려 인터널 테이블의 내용을 MODIFY하는 경우가 많다. 이런 방식의 코딩이 많아 하나의 기능을 하는 프로그램에 짧은 여러 개의 SQL이 수행된다. 일반적인 웹개발에서 긴 SQL문을 사용하는 것과 대조적이다.

 

WHERE 

operator Meaning
=, EQ True if the content of operand1 is equal to the content of operand2.
<>, NE True if the content of operand1 is not equal to the content of operand2.
<, LT True if the content of operand1 is less than the content of operand2.
>, GT True if the content of operand1 is greater than the content of operand2.
<=, LE True if the content of operand1 is less than or equal to the content of operand2.
>=, GE True if the content of operand1 is greater than or equal to the content of operand2.

 

FOR ALL ENTRIES : 인터널 테이블과 데이터베이스의 테이블을 JOIN하는 개념과 유사하다. LOOP를 수행하면서 SQL을 수행하기 때문에 데이터베이스에 반복적으로 접근하여 비효율적이지만 편리하다는 장점이 있다.

 

SELECT *
  FROM SFLIGHT
  INTO TABLE GT_SFLIGHT
   FOR ALL ENTRIES IN GT_SPFLI
 WHERE CARRID = GT_SPFLI-CARRID.

 

- WHERE 절의 조건이 한 줄이지만 native sql로 파싱되면 OR 구문을 써서 조회하는 것과 같은 방식이 된다.

 

GROUP BY 

- AVG, COUNT, MAX, MIN, STDDEV(표준편차), SUM, VARIANCE(분산) 등의 함수를 SELECT 문에 사용할 수 있게 된다.

- 위 함수 사용시 ALIAS를 지정해야 CORRESPONDING 명령어가 의도한 대로 수행된다.

 

 

ORDER BY

- 일반적인 SQL과 같음

Scalar Subquery도 일반적인 SQL문과 같은 방식으로 사용할 수 있다.

또한, EXISTS 또한 사용가능하다.

 

 

OPEN SQL : 데이터 변경(삽입,수정,삭제)

INSERT 

DATA : GS_SCARR TYPE SCARR.

GS_SCARR-CARRID = 'Z1'.
GS_SCARR-CARRNAME = 'AIR KOREA'.
GS_SCARR-URL = 'http://www.airkorea.com'.

INSERT INTO SCARR VALUES GS_SCARR.

 

- 이 때 같은 KEY값을 가져 데이터 무결성이 깨지면 DUMP ERROR를 발생시키는데 이를 방지하기 위해 ACCEPTING DUPLICATE KEYS 구문을 넣는다. INSERT 구문 실패 시 SY-SUBRC 값 4를 반환하게 한다.

 

DATA : GS_SCARR TYPE SCARR.
DATA : GT_SCARR TYPE TABLE OF SCARR.


GS_SCARR-CARRID = 'Z1'.
GS_SCARR-CARRNAME = 'AIR KOREA'.
GS_SCARR-URL = 'http://www.airkorea.com'.

APPEND GS_SCARR TO GT_SCARR.

INSERT SCARR FROM TABLE GT_SCARR ACCEPTING DUPLICATE KEYS.

WRITE : / SY-SUBRC. " 4
 
 
UPDATE
 
DATA : GS_SCARR TYPE SCARR.

GS_SCARR-CARRID = 'Z1'.
GS_SCARR-CARRNAME = 'AIR KOREA'.
GS_SCARR-URL = 'http://www.airkorea.com123'.

UPDATE SCARR FROM GS_SCARR.

WRITE : / SY-SUBRC. " 0 계속 해도 0임 즉 기존과 같은 값이어도 0
 

 

- 일반적인 SQL의 UPDATE TB_NAME SET COL1 = 'VALUE1' WHERE A=B 구조가 성능이 우수하다.

- 구조체나 테이블에 바꾸고 싶은 컬럼 이외의 값이 정의되어 있고 비어있다면 빈 값으로 UPDATE한다.

- EX) SCARR에 CURRCODE 컬럼에 이미 특정 값이 있는 데 위와 같이 UPDATE하면 CURRCODE 값은 빈 값으로 바뀌는 것이다

- 즉, 구조체나 테이블의 모든 컬럼을 비교 후에 UPDATE하기 떄문에 컬럼의 값을 직접 지정해서 바꾸는 방식이 더 성능이 좋은 것.

 

DELETE

 

DATA : GS_SCARR TYPE SCARR.
DATA : GT_SCARR TYPE TABLE OF SCARR.

GS_SCARR-CARRID = 'Z1'.
GS_SCARR-CARRNAME = 'AIR KOREA'.
GS_SCARR-URL = 'http://www.airkorea.com123'.


DELETE SCARR FROM GS_SCARR.

WRITE : / SY-SUBRC. " 삭제할 것이 없으면 4 반환

 

MODIFY = INSERT + UPDATE

- MODIFY는 INSERT와 UPDATE를 합친 기능 수행. ABAP 소스코드를 보다보면 INSERT나 UPDATE보다 MODIFY를 주로 사용하는 것을 볼 수 있다.

- 키값을 가지는 데이터가 테이블에 존재하면 UPDATE, 아니면 INSERT.

DATA : GS_SCARR TYPE SCARR.
DATA : GT_SCARR TYPE TABLE OF SCARR.

GS_SCARR-CARRID = 'Z2'.
GS_SCARR-CARRNAME = 'AIR KOREA'.
GS_SCARR-URL = 'http://www.airkorea.com'.
GS_SCARR-ZCOL2 = SY-DATUM.


APPEND GS_SCARR TO GT_SCARR.

CLEAR GS_SCARR.

GS_SCARR-CARRID = 'Z2'.
GS_SCARR-CARRNAME = 'AIR KOREA'.
GS_SCARR-URL = 'http://www.airkorea.com123'.


APPEND GS_SCARR TO GT_SCARR.

MODIFY SCARR FROM TABLE GT_SCARR.

WRITE : / SY-SUBRC.
ZCOL2의 값이 없는 것을 확인

- ZCOL2의 값이 없으므로 MODIFY가 INSERT TB_NAME FROM IT_TAB 후에 UPDATE TB_NAME FROM IT_TAB를 각각 실행하는 것을 알 수 있다.

- MODIFY를 의도에 맞게 실행하려면 모든 컬럼 데이터를 인터널 테이블이 제대로 지니고 있어야 한다는 단점이 있다. 어쩌면 ABAP 프로그램의 속도가 느리게 느껴지게 하는 주범일 수도 있을 듯

 

 

TIPS

- ORDER BY 대신 SORT를 사용하여 정렬은 AP에서 수행하는 게 낫다 - AP서버를 여러 대 두어서 그런 듯

- WHERE 조건절에 사용될 인덱스의 값이 없더라도 RANGE 변수를 활용하여 빈 값을 넣어서 NATIVE SQL로 번역될 때 조건에서 제외되지 않도록 한다.

 

 

NATIVE SQL

- 굳이 NATIVE SQL을 사용하는 경우는 크게 2가지가 있다. 데이터베이스의 기능을 활용한 정밀한 SQL 수행과 DB LINK를 통해 다른 데이터베이스에 접근하여 데이터를 가져오는 경우에 사용한다.

 

DB LINK

- DB링크의 설정은 DBCO에서 살펴볼 수 있다.

DBCO

 

DBCO에 등록 후 소스코드에서 직접 연결이름(Connection Name)을 이용해 데이터베이스에 접근하면 된다.

DB LINK를 수행하는 function module 소스 코드

- 중계 인터페이스 테이블에서 데이터를 가져오거나 반대로 중계 인터페이스 테이블에 데이터를 삽입하는 기능을 구현하기 위해 사용한다. 다만 요즘의 시스템 간 데이터 통신 방식과는 맞지 않아 계속해서 안 쓰는 추세로 바뀔 듯..

 

- Native SQL의 특이점은 MANDT(클라이언트)를 WHERE절에 써주어야 한다는 점이다. 클라이언트는 PK므로 인덱스를 사용하기 위해서는 MANDT를 설정해주어야 한다.

 

TRY.
  EXEC SQL PERFORMING F_APPEND_TABLE_HEAD.
    SELECT * INTO :IT_HEAD_INF
      FROM IF_SALE_HEADER
    WHERE SAP_RFLC_DT IS NULL
  ENDEXEC.
CATCH CX_SY_NATIVE_SQL_ERROR INTO LV_EXCEPTION.
  V_SUBRC   = 1.
  V_ERR_MSG = LV_EXCEPTION->GET_TEXT( ).
ENDTRY.
 
- DUMP ERROR가 뜨는 것을 방지하기 위해 TRY-CATCH 구문을 주로 사용하며 EXEC~ENDEXEC는 필수이다.

 

728x90

'SAP&ABAP' 카테고리의 다른 글

EASY ABAP - 7. Function  (0) 2024.04.08
EASY ABAP - 6. Subroutine  (0) 2024.04.08
EASY ABAP - 4-2. Data Type(2)  (0) 2024.04.04
EASY ABAP - 4-1. Data Type(1)  (0) 2024.04.04
EASY ABAP - 3. TMS와 CTS  (2) 2024.04.04