본문 바로가기

Database/공부공부

[SQL] INSERT INTO ... SELECT 구문 (Dual 테이블)

 

 

* DUAL : 특수한 단일 행 테이블.

=> 데이터를 조회할 대상이 없을 때, 테이블 없이 간단한 연산이나 함수 결과를 반환할 떄 사용.

 

ex) 테이블 없이 상수, 연산결과 등을 반환.

// 상수 반환
SELECT 'Hello World' FROM DUAL;	
SELECT 1 FROM DUAL;

// 함수 결과 반환
SELECT SYSDATE FROM DUAL;

// 연산 수행
SELECT 2 + 3 FROM DUAL;

// 다중 행 반환
SELECT 'Current Time: ' || TO_CHAR(SYSDATE, 'HH24:MI:SS') FROM DUAL;

 

** MySQL 에서는 FROM DUAL 생략 가능.

SELECT 1;

 

 


 

* INSERT 

INSERT INTO table_name (column1, column2, column3)
VALUES (value1, value2, value3);

 

 

* INSERT INTO ... SELECT

INSERT INTO table_name (column1, column2, column3)
SELECT value1, value2, value3 FROM DUAL;

=> 동적으로 데이터를 생성하거나, 다른 테이블의 데이터를 삽입할 때 사용하는 방식.

 


 

ex) DUAL 활용.

INSERT INTO my_table (column1, column2)
SELECT 'Hello', NOW() FROM DUAL;

 

 

ex) 다른 테이블의 데이터 삽입.

INSERT INTO archive_table (id, name)
SELECT id, name FROM main_table WHERE status = 'inactive';

 

 

ex) NOT EXISTS 활용. (중복 방지 삽입)

INSERT INTO my_table (id, name)
SELECT 1, 'John Doe'
FROM DUAL
WHERE NOT EXISTS (
    SELECT 1 FROM my_table WHERE id = 1
);

 

 

ex) MyBatis 파라미터 바인딩 활용. (중복 방지 삽입)

<insert id="insertUserIfNotExists" parameterType="java.util.HashMap">
    INSERT INTO users (
        user_id,
        username,
        email,
        created_at
    )
    SELECT 
        #{userId},       -- 파라미터로 전달된 userId
        #{username},     -- 파라미터로 전달된 username
        #{email},        -- 파라미터로 전달된 email
        NOW()            -- 현재 시간 (created_at)
    FROM DUAL
    WHERE NOT EXISTS (
        SELECT 1 FROM users 
        WHERE user_id = #{userId}
    );
</insert>

=> 파라미터로 가져온 userId가 존재하지 않는 경우에만 사용자 정보를 저장.

*** 하나의 트랜잭션 내에서 중복 확인과 데이터 삽입을 동시게 처리할 수 있는 안전한 방식.