MySQL ON DUPLICATE KEY UPDATE 관련 질문입니다. 0 10 2,952

by 찡스쿄 [MySQL] MySQL ON DUPLICATE KEY UPDATE [2020.11.05 10:30:33]



안녕하세요, 선배님들 계정 정보를 생성하는 다음의 SQL 문이 있습니다.

헌데, 비밀번호의 경우에는 파라미터로 전달받은 경우에만 UPDATE를 해주고 싶은데,

앞의 INSERT 문이 실행되면서 'CHARGE_PW CAN NOT BE NULL' 오류가 발생하고 있습니다.

ON DUPLICAET KEY UPDATE를 이용할 때 다음의 쿼리와 같이

동적으로 처리할 수 있는 방법이 없을까요?..

답변 미리 감사드립니다.


         INSERT INTO TB_CHARGE_MG (
			  CHARGE_SQ
			, ASSIGN_SQ
			, CHARGE_NM
			, CHARGE_ID
			, CHARGE_PWD
			, USE_YN
			, CHARGE_AUTH
			, REGISTER_DT
			, MODIFY_DT
		) VALUES (
			  #{chargeSq}
			, #{assignSq}
			, #{chargeNm}
			, #{chargeId}
			, #{chargePwd}
			, #{useYn}
			, #{chargeAuth}
			, NOW()
			, NULL
		) ON DUPLICATE KEY UPDATE
			  MODIFY_DT = NOW()
			, CHARGE_NM = #{chargeNm}
			, CHARGE_ID = #{chargeId}
			, USE_YN = #{useYn}
			, CHARGE_AUTH = #{chargeAuth}
			=== if 조건이 들어갑니다 ===
			, CHARGE_PWD = #{chargePwd}

                               =====================

 

 

by 마농 [2020.11.05 10:57:54]

- 변경전 : , CHARGE_PWD = #{chargePwd}
- 변경후 : , CHARGE_PWD = IFNULL(#{chargePwd}, CHARGE_PWD)


by 찡스쿄 [2020.11.05 11:05:57]
마농 선생님 답변 감사드립니다. ^^
말씀하신 대로 변경해 보았지만 다음과 같이 쿼리가 실행되고, 오류가 발생하고 있습니다.
비밀번호의 경우는 변경할 수도, 변경하지 않을 수도 있기에
NULL이 들어올 수 있다는 가정하에 작성한 쿼리입니다.

INSERT INTO TB_CHARGE_MG (

		  CHARGE_SQ
		, ASSIGN_SQ
		, CHARGE_NM
		, CHARGE_ID
		, CHARGE_PWD
		, USE_YN
		, CHARGE_AUTH
		, REGISTER_DT
		, MODIFY_DT

		) VALUES (
			  1
			, 1
			, '관리자'
			, 'admin'
			, NULL
			, 'Y'
			, 'A'
			, NOW()
			, NULL
		) ON DUPLICATE KEY UPDATE
			  MODIFY_DT = NOW()
			, CHARGE_NM = '관리자'
			, CHARGE_ID = 'admin'
			, USE_YN = 'Y'
			, CHARGE_AUTH = 'A'
			, CHARGE_PWD = IFNULL(NULL, CHARGE_PWD)


Exception : Column 'CHARGE_PWD' cannot be null


by 마농 [2020.11.05 11:46:09]

테스트 쿼리가 오류난 이유가
Update 를 탄게 아니라 Insert 를 타면서 오류난게 아닐까요?
Insert 를 타야 하는 경우에는 널이 들어오면 안되죠.


by 찡스쿄 [2020.11.05 13:49:19]

마농 선생님 답변 감사드립니다.

말씀하신 대로라면 계정 정보 생성이나 업데이트에는 ON DUPLICATE KEY UPDATE를

이용하면 안 되는 걸까요?.. 패스워드는 변경이 필요할 수도, 필요하지 않을 수도 있어서요..


by 마농 [2020.11.05 14:52:35]

잘못 이해하신 듯 합니다.
ON DUPLICATE KEY UPDATE를 이용하지 말라는게 아닙니다.
또한 요청하신 오류부분을 해결해 드린 것이구요.
다만 테스트 데이터가 잘못 된 듯 합니다.
업데이트가 아닌 인서트를 타는 데이터로 NULL 입력 테스트 하신 듯 합니다.
인서트가 아닌 업데이트를 타는 데이터로 NULL 입력 테스트를 해보세요.
인서트를 타는 데이터라면? 당연히 널이 들어오면 안되구요.

혹시? 테스트 데이터에 문제가 없는데도 해당오류가 난다면?
dup 오류보다 null 오류가 우선인가 보네요.
INSERT 구문 쪽에도 강제로 IFNULL 처리를 해주세요.
- 변경전 : , #{chargePwd}
- 변경후 : , IFNULL(#{chargePwd}, 'x')


by 찡스쿄 [2020.11.05 15:51:03]

답변 감사드립니다, 선생님.

ON DUPLICATE KEY UPDATE를 이용하면

PK가 포함되지 않았을 때 INSERT가 실행되고,

PK가 포함되었을 떄 아래의 UPDATE 구문을 타는 것으로 이해하고 있습니다만..

해당 쿼리를 호출하였을 때 INSERT 문의 chargePwd에

NULL이 들어가기 때문에 오류가 발생하고 있습니다.

선생님께서 말씀하신 것처럼 INSERT 문의 CHARGE_PWD를

강제로 IFNULL로 처리하면 잘 INSERT가 되고 있습니다만..

이게 맞는 방식인지에 대해 의문이 생깁니다 ㅠ_ㅠ..


by 마농 [2020.11.05 16:18:05]

insert 문에서는 ifnull 을 하더라도
- 실제 인서트 대상 이라면 널이 들어올 리가 없으니 상관이 없구요.
- 실제 인서트 대상이 아니라면 dup 에러로 update 구문으로 넘어갈 것이므로 상관이 없지요.


by 찡스쿄 [2020.11.06 09:17:28]

마농 선생님 답변 감사드립니다. ^^

어젠 갑자기 다른 업무가 들어와 급하게 처리하느라 이제야 보게 되었네요..

이게.. PK 값을 파라미터에 포함시켜서 해당 쿼리를 실행해도 UPDATE 문으로 넘어가지 않고,

INSERT가 실행된 후에 UPDATE 구문으로 넘어가는 듯합니다.

MyBatis 프레임워크에서는 무조건 INSERT를 실행한 뒤에 UPDATE 구문을 실행하는 것 같습니다.


by 마농 [2020.11.06 09:21:44]

네. 오라클의 머지문과는 다른 개념인 듯 하네요.
위에 언급한대로 양쪽 다 ifnull 처리 해도 문제 없을 듯 합니다.
다만, 신규 insert 대상이라면? null 이 들어오지 않도록 화면에서 강제 처리 해줘야 합니다.


by 찡스쿄 [2020.11.06 10:37:30]

답변 감사드립니다. ^^

저번부터 마농 선생님께 배워가는 것이 많네요 ㅠㅠ..

한 주 마무리 잘 하시고, 좋은 일만 가득하시기 바랍니다!

다시 한번 감사드려요 ^^~

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입