Oracle의 MERGE INTO 기초

Database를 Oracle를 사용할때 유용하게 사용하는 Merge Into에 대해서 간단하게 정리.

개인적으로 실서비스에서는 크게 사용한적은 없는 것 같고 Admin이나 배치 개발시에 MyBatis와 함께 유용하게 사용하고 있다.

요구사항 : 상품이 있으면 수정하고 없으면 삽입해라.

기존 Update와 Insert 만 사용예시

mybatis를 사용한다고 했을때 가장 간단하게 처리하는 방법은 아래와 같다.

  1. 우선 Update query를 실행한 후 update 된 행의 개수를 resultType으로 return

  2. Insert into query실행.(위 update의 update rows가 0인 경우에만 실행.)

Update Query 예시.


UPDATE PRODUCT pd
SET USE_YN = #{useYn}
,PRODUCT_NAME = #{productName}
,MODIFY_DATE = SYSDATE
   WHERE pd.PRODUCT_ID = #{productId}

Insert Query 예시.

INSERT INTO PRODUCT (
    PRODUCT_ID
    , PRODUCT_NAME
    , USE_YN
    , MODIFY_DATE
  ) values (
    #{productId}
    , #{productName}
    , #{useYn}
    , SYSDATE
  )

Merge into 사용하기(Update 와 Insert 합치기.)

위 요구사항을 Merge Into를 이용하여 구현하면 아래와 같다.

기본적인 사용법은 너무 간단해서 따로 추가 내용은 필요가 없을 정도이다.

레퍼런스 사이트에 가면 좀 더 디테일 하게 내용을 확인 할 수 있다.

Merge into Query with comment

많이 사용하는 구성은 의외로 간단하다. 다만 생각해야 할 것은 Update 또는 Insert를 한번에 처리하므로 Parameter값을 잘 생각해서 주어야 한다.

MERGE INTO Product pd /* 대상이 되는 테이블 또는 뷰*/
USING DUAL /* 위의 하나의 테이블만 이용할려면 DUAL을 적으면 됨.*/
ON ( pd.PRODUCT_ID = #{productId} ) /* ON 에 해당되는 데이타가 UPDATE시 Rows가 됨. */
WHEN MATCHED THEN /* ON 조건에 해당되는 것이 있으면 아래 실행(UPDATE) */
UPDATE SET       /* Update시 테이블명이나 Where조건이 모두 위에 있다고 생각하면 됨 */
USE_YN = #{useYn}
,PRODUCT_NAME = #{productName}
,MODIFY_DATE = SYSDATE
WHEN NOT MATCHED THEN /* ON 조건에 매칭되지 않으면 아래 실행(Insert)*/
INSERT ( /* INSERT INTO PRODUCT -> INSERT로 퉁쳤다는걸 기억하다. */
    PRODUCT_ID
    , PRODUCT_NAME
    , USE_YN
    , MODIFY_DATE
  ) values (
    #{productId}
    , #{productName}
    , #{useYn}
    , SYSDATE
  )

Merge into Query without comment


MERGE INTO Product pd
USING DUAL
ON ( pd.PRODUCT_ID = #{productId} )
WHEN MATCHED THEN
UPDATE SET
USE_YN = #{useYn}
,PRODUCT_NAME = #{productName}
,MODIFY_DATE = SYSDATE
WHEN NOT MATCHED THEN
INSERT (
    PRODUCT_ID
    , PRODUCT_NAME
    , USE_YN
    , MODIFY_DATE
  ) values (
    #{productId}
    , #{productName}
    , #{useYn}
    , SYSDATE
  )

Syntax diagram

아래는 Oracle 내 레퍼런스 사이트내 Merge Into에 대한 syntax diagram이다.

https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9016.htm#SQLRF01606



merge_update_caluse 구문



merge_insert_clause 구문

'Database' 카테고리의 다른 글

java.sql.SQLSyntaxErrorException: ORA-00911: 문자가 부적합합니다  (0) 2017.12.22
Mysql 사용자 팁  (0) 2014.12.02
Posted by 다인,보리아빠
,



Mybatis시 아래와 같이 에러가 났다면 십중팔구 해당 쿼리에 세미콜론이 있는지 확인하세요.


### Cause: java.sql.SQLSyntaxErrorException: ORA-00911: 문자가 부적합합니다

; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00911: 문자가 부적합합니다

at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:91)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:371)
at com.sun.proxy.$Proxy44.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:198)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:119)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:63)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:52)

'Database' 카테고리의 다른 글

Oracle의 MERGE INTO 기초  (1) 2018.01.02
Mysql 사용자 팁  (0) 2014.12.02
Posted by 다인,보리아빠
,

Mysql 사용자 팁

Database 2014. 12. 2. 10:25
mysql 사용시 콘솔내에서 유용하게 사용할 수 있는 방법 몇가지를 정리합니다.

Query 세로 보기
접속자 및 현재 실행중인 Query 확인
테이블 정보 요약

1. 결과 세로로 보기
# 세로보기
mysql> select now()\G
*************************** 1. row ***************************
now(): 2014-12-02 09:30:37
1 row in set (0.00 sec)

#기존의 가로보기
mysql> select now(); 또는 select now()\g 
+---------------------+
| now() |
+---------------------+
| 2014-12-02 09:30:30  |
+---------------------+
1 row in set (0.00 sec)
2. mysql 접속자 및 현재 실행중인 query 확인
mysql> show processlist;
+-------+-----------+-----------------+--------+---------+-------+-------+------------------+
| Id  | User| Host | db  | Command | Time| State | Info  |
+-------+-----------+-----------------+--------+---------+-------+-------+------------------+
| 14965 | test| localhost:54679 | test | Sleep  | 18056 || NULL|
| 15053 | test| localhost:58070 | test | Sleep  | 15126 || NULL|
| 15283 | test| localhost:59917 | test | Sleep  |  7801  || NULL|
| 15362 | test| localhost:50901 | test | Sleep  |  4872  || NULL|
| 15412 | test| localhost:48443 | test | Sleep  |  2672  || select * from TEST_TABLE .......... |
| 15487 | root| localhost| mysql | Query  |  0 | NULL | show processlist |
+-------+-----------+-----------------+--------+---------+-------+-------+------------------+
6 rows in set (0.00 sec)
위와 같이 실행하면 긴 query 의 경우 잘려서 노출이 되게 된다.
긴 query에 대해 전체 출력을 하고자 한다면 아래와 같이 한다.
mysql> show full processlist;
+-------+-----------+-----------------+--------+---------+-------+-------+------------------+
| Id  | User| Host | db  | Command | Time| State | Info|
+-------+-----------+-----------------+--------+---------+-------+-------+------------------+
| 14965 | test  | localhost:54679 | test | Sleep  | 18056 || NULL|
| 15053 | test  | localhost:58070 | test | Sleep  | 15126 || NULL|
| 15283 | test  | localhost:59917 | test | Sleep  |  7801  || NULL|
| 15362 | test  | localhost:50901 | test | Sleep  |  4872  || NULL|
| 15412 | test | localhost:48443 | test | Sleep  |  2672  || select * from TEST_TABLE where devcoding = 10|
| 15487 | root  | localhost | mysql | Query  |  0 | NULL | show processlist |
+-------+-----------+-----------------+--------+---------+-------+-------+------------------+
6 rows in set (0.00 sec)

3. 현재 데이타베이스의 테이블 정보

mysql> show table status\G
*************************** 1. row ***************************
Name: columns_priv
 Engine: MyISAM
Version: 10
Row_format: Fixed
Rows: 0
 Avg_row_length: 0
 Data_length: 0
Max_data_length: 227994731135631359
Index_length: 1024
 Data_free: 0
  Auto_increment: NULL
 Create_time: 2009-03-24 23:25:43
 Update_time: 2009-03-24 23:25:43
Check_time: NULL
 Collation: utf8_bin
 Checksum: NULL
 Create_options:
  Comment: Column privileges
*************************** 2. row ***************************
.
.
.
.


Posted by 다인,보리아빠
,