DB 아웃바운드 룰

개요

DB 아웃바운드 룰은 데이터베이스에 SQL 쿼리를 실행하기 위한 규칙을 정의합니다. SELECT, INSERT, UPDATE, DELETE 등의 SQL 쿼리를 실행하고 실행 결과를 메시지에 매핑할 수 있습니다.

DB 아웃바운드 룰 생성

리소스 트리에서 원하는 거래 또는 거래그룹의 컨텍스트 메뉴를 열고 [리소스 생성] > [아웃바운드 룰] > [DB 생성]을 선택합니다.

DB 아웃바운드 룰 생성 화면은 [DB 아웃바운드 룰] 탭과 [룰 SQL] 탭으로 구성됩니다. 설정 정보를 입력하고 탭 하단의 [생성] 버튼을 클릭합니다.

outbound rule create db

다음은 [DB 아웃바운드 룰] 탭의 화면 구성입니다.

  • 기본 정보 설정

    모든 아웃바운드 룰에 공통으로 적용되는 설정 항목입니다. 설정 방법은 공통 설정 항목을 참고합니다.

  • 요청/응답 메시지 설정

    아웃바운드 룰의 요청 및 응답 메시지를 설정합니다. 설정 방법은 요청/응답 메시지 설정을 참고합니다.

다음은 [룰 SQL] 탭의 화면 구성입니다.

outbound rule create db rule sql
  • ① SQL 에디터

    SQL 쿼리를 작성하고 SQL 실행 결과를 메시지 필드에 매핑할 수 있습니다. 최소 1개의 SQL이 작성되어야 하며, 여러 개의 SQL을 순차적으로 실행할 수 있습니다.

    SQL 쿼리를 작성하는 방법은 SQL 작성을 참고합니다.

    SQL 쿼리가 작성되지 않으면 아웃바운드 룰이 올바르게 동작하지 않습니다.

    버튼 설명

    [출력 매핑]

    SQL 실행 결과를 메시지 필드에 매핑합니다. 주로 SELECT 쿼리에서 사용됩니다.

    매핑 방법은 SQL 출력 매핑을 참고합니다.

    [문법 체크]

    문법 검증 및 자동 정렬이 수행됩니다. Ctrl + S을 눌러도 동일하게 수행됩니다.

    하단의 자동 정렬 체크박스를 해제하면 문법 오류 검사만 수행합니다. 문법 검증은 선택한 데이터베이스 종류를 기준으로 수행되며, 현재 MariaDB, MySQL, PostgreSQL을 지원합니다.

  • ② 입력 스키마

    [DB 아웃바운드 룰] 탭에서 설정한 요청 메시지의 필드가 표시됩니다. 요청 메시지 필드를 SQL 에디터로 드래그 앤 드롭하여 매핑 소스 컬럼으로 사용할 수 있습니다.

SQL 작성

SQL 에디터에서 작성할 수 있습니다.

다음은 지원되는 SQL 쿼리와 각 쿼리의 수행 결과입니다.

쿼리 설명

SELECT

데이터를 조회합니다. 결과를 응답 메시지에 매핑합니다.

INSERT

데이터를 삽입합니다. 영향받은 행 수를 반환합니다.

UPDATE

데이터를 수정합니다. 영향받은 행 수를 반환합니다.

DELETE

데이터를 삭제합니다. 영향받은 행 수를 반환합니다.

다음은 SQL SELECT 쿼리의 작성 예시입니다.

SELECT customer_id, customer_name, email
FROM customers
WHERE status = 'ACTIVE'

SQL 출력 매핑

SQL 실행 결과를 응답 메시지에 매핑하려면 SQL 에디터에서 [출력 매핑] 버튼을 클릭합니다. [출력 매핑] 버튼은 다음 조건을 모두 만족할 때만 활성화됩니다.

  • 응답 메시지가 1개 이상 설정되어 있어야 합니다.

  • SQL 쿼리에서 출력 가능한 필드가 존재해야 합니다.

SQL 문법 오류가 있는 경우에도 [출력 매핑] 버튼이 비활성화됩니다.

SQL 쿼리를 작성 및 실행 후 [출력 매핑] 버튼을 클릭하면 매핑 다이얼로그가 표시됩니다.

SELECT 쿼리를 실행한 경우 조회된 컬럼과 함께 Row Count 필드가 표시됩니다. Row Count 필드는 조회된 행(row) 수입니다.

outbound rule db select mapping field

INSERT, UPDATE, DELETE 쿼리를 실행한 경우 Affected Count, Success Count 필드가 표시됩니다.

outbound rule db mapping field

Affected Count 필드는 SQL 실행으로 영향받은 행 수입니다. 실행 결과에 따라 0 이상의 값이 반환됩니다. Success Count 필드는 성공적으로 실행된 SQL 수입니다.

SQL이 성공적으로 실행되었는지 여부는 Success Count를 기준으로, 실제로 변경된 행이 있는지 여부는 Affected Count를 기준으로 판단합니다.

SELECT 쿼리는 Row Count 필드만, INSERT, UPDATE, DELETE 쿼리는 Affected Count, Success Count 필드만 출력 매핑에 사용할 수 있습니다.

출력 매핑은 모든 SQL 쿼리에서 선택 사항입니다. SELECT 쿼리는 조회 결과를 응답 메시지에 매핑하지 않으면 조회된 데이터를 사용할 수 없으므로 설정을 권장합니다.

Affected Count가 0인 경우

SQL이 정상적으로 실행되더라도 Affected Count는 0으로 반환될 수 있으며, 이는 오류가 아닙니다. Success Count가 1이면 SQL은 정상적으로 실행된 것입니다.

다음과 같은 경우에는 Affected Count가 0으로 반환될 수 있습니다.

  • UPDATE / DELETE 쿼리 실행 시 WHERE 조건에 일치하는 행이 없는 경우

  • CREATE, DROP, ALTER, TRUNCATE 등의 DDL 구문 (행 단위 처리가 아니므로 항상 0을 반환)

  • MySQL / MariaDB에서 INSERT IGNORE 실행 시 삽입 대상이 모두 중복 키인 경우

DB 타입별 Affected Count 기준

Affected Count는 SQL 실행으로 영향을 받은 행 수를 의미합니다. 데이터베이스의 종류에 따라 Affected Count를 계산하는 기준이 다릅니다.

Affected Count의 의미는 데이터베이스 종류에 따라 다를 수 있으므로, 동일한 SQL이라도 DB 타입에 따라 결과 값이 다르게 나타날 수 있습니다.

  • MySQL / MariaDB - UPDATE 쿼리

    MySQL 및 MariaDB는 기본적으로 WHERE 조건에 일치하는 행 수를 Affected Count로 반환합니다. 따라서 실제로 값이 변경되지 않은 경우에도 Affected Count에 포함될 수 있습니다.

    반면, Oracle 및 PostgreSQL은 실제로 값이 변경된 행 수를 반환합니다.

    벤더 Affected Count 기준

    Oracle / PostgreSQL

    실제로 값이 변경된 행 수

    MySQL / MariaDB

    WHERE 조건에 일치하는 행 수 (값 변경 여부와 무관)

  • MySQL / MariaDB - INSERT 쿼리

    다음은 MySQL / MariaDB에서 INSERT 계열 쿼리 실행 시 Affected Count의 반환 기준입니다.

    구문 Affected Count 이유

    INSERT …​ ON DUPLICATE KEY UPDATE
    (값 변경 발생)

    2

    내부적으로 기존 행 삭제 후 다시 삽입된 것으로 처리됩니다. (DELETE + INSERT)

    REPLACE INTO (기존 행 교체)

    2

    내부적으로 기존 행 삭제 후 다시 삽입됩니다. (DELETE + INSERT)

    INSERT …​ ON DUPLICATE KEY UPDATE
    (값 변경 없음)

    0

    실제 데이터 변경이 없으므로 0이 반환됩니다.

  • MySQL / MariaDB - JDBC 드라이버 동작

    MariaDB 및 MySQL JDBC 드라이버는 기본적으로 실제 변경된 행 수가 아닌 조건에 일치하는 행 수를 반환할 수 있습니다.

    이로 인해 INSERT …​ ON DUPLICATE KEY UPDATE 실행 시 값 변경이 없더라도 Affected Count가 0이 아닌 1로 반환될 수 있습니다.

    실제 데이터 변경 여부를 기준으로 판단하려면 JDBC URL에 다음 옵션을 추가해야 합니다.

    useAffectedRows=true

    다음은 JDBC URL에 옵션을 추가한 예시입니다.

    jdbc:mariadb://host:port/database?useAffectedRows=true

SQL 출력 매핑 예시

다음은 SQL 실행 결과의 각 컬럼을 응답 메시지 필드에 매핑하는 예시입니다.

SQL 결과 컬럼          →  응답 메시지 필드
-----------------          -----------------
customer_id           →  customerId
customer_name         →  customerName
email                 →  email
registration_date     →  registrationDate
단일 행 결과

SELECT 실행 결과가 단일 행인 경우 각 컬럼 값이 해당 필드에 직접 매핑됩니다.

SQL: SELECT customer_id, customer_name FROM customers WHERE id = '${CustomerSearchRequest/id}'

결과:
| customer_id | customer_name |
|-------------|---------------|
| C001        | 홍길동        |

매핑 결과:
{
  "customerId": "C001",
  "customerName": "홍길동"
}
다중 행 결과

SELECT 실행 결과가 여러 행인 경우 배열로 매핑됩니다.

SQL: SELECT order_id, order_date FROM orders WHERE customer_id = '${OrderSearchRequest/customerId}'

결과:
| order_id | order_date |
|----------|------------|
| ORD001   | 2025-02-01 |
| ORD002   | 2025-02-03 |
| ORD003   | 2025-02-05 |

매핑 결과 (배열 필드인 경우):
{
  "orders": [
    {"orderId": "ORD001", "orderDate": "2025-02-01"},
    {"orderId": "ORD002", "orderDate": "2025-02-03"},
    {"orderId": "ORD003", "orderDate": "2025-02-05"}
  ]
}
다중 쿼리

여러 개의 SQL을 순차적으로 실행할 수 있습니다.

다음은 다중 쿼리 실행 예시입니다.

-- SQL #0: 고객 정보 조회
SELECT customer_id, customer_name
FROM customers
WHERE customer_id = '${CustomerInfoRequest/customerId}'

-- SQL #1: 주문 목록 조회
SELECT order_id, order_date, total_amount
FROM orders
WHERE customer_id = '${CustomerInfoRequest/customerId}'
ORDER BY order_date DESC

-- SQL #2: 적립 포인트 조회
SELECT point_balance
FROM customer_points
WHERE customer_id = '${CustomerInfoRequest/customerId}'

다음은 위 SQL 쿼리 실행 결과를 응답 메시지 필드에 매핑하는 예시입니다.

인덱스 0 (고객 정보):
  customer_id → customerId
  customer_name → customerName

인덱스 1 (주문 목록):
  order_id → orders[].orderId
  order_date → orders[].orderDate
  total_amount → orders[].totalAmount

인덱스 2 (적립 포인트):
  point_balance → pointBalance

다중 쿼리는 단일 트랜잭션 내에서 실행됩니다. 하나의 쿼리가 실패하면 전체 트랜잭션이 롤백됩니다.

SQL 파라미터 바인딩

SQL 작성 시 요청 메시지의 필드를 파라미터로 참조하여 사용할 수 있습니다.

[룰 SQL] 탭의 입력 스키마에 표시된 요청 메시지의 필드를 SQL 에디터에 드래그 앤 드롭합니다.

요청 메시지 필드는 ${MessageId/FieldId} 형식으로 참조하며, SELECT 컬럼, WHERE 조건, VALUES 등 SQL의 다양한 위치에서 사용할 수 있습니다.

db rule sql parameter binding
구성 요소 설명

MessageId

요청 메시지의 ID이며, 실제 메시지 ID와 정확히 일치해야 합니다.

FieldId

요청 메시지 내 필드의 ID이며, 실제 필드 ID와 정확히 일치해야 합니다.

SQL 파라미터는 사용 위치에 따라 다음과 같이 입력합니다.

위치 설명

파라미터를 값(value) 으로 사용하는 경우

문자열 타입은 '${MessageId/FieldId}'와 같이 작은따옴표('')로 감싸서 사용하고, 숫자 타입(INT, LONG 등)은 따옴표 없이 사용합니다.

파라미터를 식별자(컬럼명, 테이블명 등)로 사용하는 경우

데이터 타입과 관계없이 따옴표를 사용하지 않습니다.

필드 값이 null인 경우

SQL NULL로 바인딩됩니다.

다음은 요청 메시지 필드를 SQL 파라미터로 바인딩하는 예시입니다.

SELECT order_id, order_date, total_amount
FROM orders
WHERE customer_id = '${OrderSearchRequest/customerId}'
  AND order_date >= '${OrderSearchRequest/startDate}'
  AND order_date <= '${OrderSearchRequest/endDate}'
  AND status = '${OrderSearchRequest/status}'

위 예시에서 ${OrderSearchRequest/customerId} 등의 파라미터는 실행 시점에 요청 메시지의 해당 필드 값으로 대체됩니다.

다음은 복잡한 바인딩 예시입니다.

SELECT ${OrderSearchRequest/selectCol1}, ${OrderSearchRequest/selectCol2},
       quantity, unit_price
FROM orders
WHERE customer_id = '${OrderSearchRequest/customerId}'
  AND status = '${OrderSearchRequest/status}'
  AND quantity >= ${OrderSearchRequest/minQuantity}
  AND unit_price <= ${OrderSearchRequest/maxUnitPrice}

위 예시에서 ${OrderSearchRequest/selectCol1}, ${OrderSearchRequest/selectCol2}는 컬럼명(식별자)으로 대체되므로 따옴표를 사용하지 않습니다.

사용 예시

SELECT 쿼리

데이터 조회 시나리오의 설정 예시입니다.

프로토콜: DB
타임아웃: 30000ms (30초)

SQL 에디터:
  SELECT product_id, product_name, price, stock_quantity
  FROM products
  WHERE category = '${ProductSearchRequest/category}'
    AND price <= ${ProductSearchRequest/maxPrice}
    AND stock_quantity > 0
  ORDER BY price ASC

요청 메시지: ProductSearchRequest
  - category: STRING
  - maxPrice: LONG

응답 메시지: ProductSearchResponse
  - products: OBJECT (배열)
    - productId: STRING
    - productName: STRING
    - price: LONG
    - stockQuantity: INT

출력 매핑:
  인덱스 0:
    product_id → productId
    product_name → productName
    price → price
    stock_quantity → stockQuantity

INSERT 쿼리

데이터 삽입 시나리오의 설정 예시입니다.

프로토콜: DB
타임아웃: 10000ms (10초)

SQL 에디터:
  INSERT INTO orders (
    order_id, customer_id, order_date,
    total_amount, status
  )
  VALUES (
    '${OrderCreateRequest/orderId}', '${OrderCreateRequest/customerId}',
    '${OrderCreateRequest/orderDate}', ${OrderCreateRequest/totalAmount}, 'PENDING'
  )

요청 메시지: OrderCreateRequest
  - orderId: STRING
  - customerId: STRING
  - orderDate: STRING
  - totalAmount: LONG

UPDATE 쿼리

데이터 수정 시나리오의 설정 예시입니다.

프로토콜: DB
타임아웃: 10000ms (10초)

SQL 에디터:
  UPDATE orders
  SET status = '${OrderStatusUpdateRequest/newStatus}',
      updated_at = NOW()
  WHERE order_id = '${OrderStatusUpdateRequest/orderId}'
    AND status = '${OrderStatusUpdateRequest/currentStatus}'

요청 메시지: OrderStatusUpdateRequest
  - orderId: STRING
  - currentStatus: STRING
  - newStatus: STRING

복합 트랜잭션

여러 테이블에 걸친 복합 트랜잭션 시나리오의 설정 예시입니다.

프로토콜: DB
타임아웃: 30000ms (30초)

SQL 에디터:
  -- SQL #0: 주문 생성
  INSERT INTO orders (order_id, customer_id, total_amount, status)
  VALUES ('${OrderProcessRequest/orderId}', '${OrderProcessRequest/customerId}',
          ${OrderProcessRequest/totalAmount}, 'CONFIRMED')

  -- SQL #1: 주문 상세 생성
  INSERT INTO order_items (order_id, product_id, quantity, unit_price)
  VALUES ('${OrderProcessRequest/orderId}', '${OrderProcessRequest/productId}',
          ${OrderProcessRequest/quantity}, ${OrderProcessRequest/unitPrice})

  -- SQL #2: 재고 차감
  UPDATE products
  SET stock_quantity = stock_quantity - ${OrderProcessRequest/quantity}
  WHERE product_id = '${OrderProcessRequest/productId}'

  -- SQL #3: 포인트 적립
  UPDATE customer_points
  SET point_balance = point_balance + ${OrderProcessRequest/earnedPoints}
  WHERE customer_id = '${OrderProcessRequest/customerId}'

요청 메시지: OrderProcessRequest
  - orderId: STRING
  - customerId: STRING
  - productId: STRING
  - quantity: INT
  - unitPrice: LONG
  - totalAmount: LONG
  - earnedPoints: INT