MYSQL UPSERT

ON DUPLICATE KEY

Posted by ETHAN KIM on February 08, 2022 · 3 mins read
PHP

UPSERT

INSERT 시 pk중복 데이터는 알아서 UPDATE 처리


기존방식

pk 이외의 값으로 SELECT 하여 중복데이터 체크 중복값이 존재할 경우 UPDATE 존재하지 않을 경우 INSERT


        $sql2 = " select io_no, count(*) as cnt from shop_goods_option where gs_id = '$gs_id' and io_id = '$io_id_chr' and io_type = '$io_type' ";
        $row2 = sql_fetch($sql2);
        if($row2['cnt']) {
            $update_gcode[] = $gcode;
            $update_count++;

	        $sql = " update shop_goods_option
                        set io_id = '$io_id_chr'
			  , io_type = '$io_type'
			  , gs_id = '$gs_id'
			  , io_price = '$io_price'
			  , io_stock_qty = '$io_stock_qty'
			  , io_noti_qty = '$io_noti_qty'
			  , io_use = '$io_use'	
			  where io_no = '$row2[io_no]' ";
		sql_query($sql);

	} else { // 옵션 테이블 insert
		$sql = " insert into shop_goods_option
                        set io_id = '$io_id_chr'
			  , io_type = '$io_type'
			  , gs_id = '$gs_id'
			  , io_price = '$io_price'
			  , io_stock_qty = '$io_stock_qty'
			  , io_noti_qty = '$io_noti_qty'
			  , io_use = '$io_use' ";
	        sql_query($sql);

		$succ_count++;
	}


UPSERT 사용

pk 값을 포함하여 insert문 작성 / ON DUPLICATE KEY UPDATE에서 pk값 제외하고 update문 작성


	$sql = " INSERT INTO shop_goods_option
			(
				io_no,
				io_id,
				io_type,
				gs_id,
				io_price,
				io_stock_qty,
				io_noti_qty,
				io_use
			) VALUES (
				'$io_no',
				'$io_id_chr',
				'$io_type',
				'$gs_id',
				'$io_price',
				'$io_stock_qty',
				'$io_noti_qty',
				'$io_use'					
			) ON DUPLICATE KEY UPDATE 
				io_id = '$io_id_chr',
				io_type = '$io_type',
				gs_id = '$gs_id',
				io_price = '$io_price',
				io_stock_qty = '$io_stock_qty',
				io_noti_qty = '$io_noti_qty',
				io_use = '$io_use' ";
	$result = sql_query($sql);

	if($io_no == '신규'){
		$succ_gcode[] = $gcode;
		$succ_count++;				
	}else{
		$update_gcode[] = $gcode;
		$update_count++;					
	};


참고

MYSQL 4.1버전부터 지원
REPLACE를 사용하는 방법과 동일하나, REPLACE의 경우 삭제 후 다시 INSERT 하는 과정을 거치기 때문에,
쿼리 횟수 감소 및 row 조회수 면에서 UPSERT를 사용하는 편이 효율적으로 보임.
INSERT를 하였는지 UPDATE를 하였는지에 대한 쿼리 return값은 php의 경우 ‘1’로 동일하므로 구분할 수가 없다.
but, JAVA의 경우 INSERT는 1 UPDATE는 2로 결과값을 통한 구분이 가능하다고 함.