C++에서 API를 통해 MYSQL의 Query를 실행하는 와중에
commands out of sync you can't run this command now |
라는 에러 메시지가 출력되며 Query가 작동하지 않았다.
공식 홈페이지에서는 mysql_use_result()를 사용 하고 mysql_free_result()를 호출해 리소스를 해제하기 전에 또 다시 Query를 시도하면 발생할 수 있다고 한다. 또는 mysql_use_result() 또는 mysql_store_result() 호출하지 않고 데이터를 반환하는 2개의 Query를 실행하려고 할 때도 발생한다고도 한다.
https://dev.mysql.com/doc/refman/8.0/en/commands-out-of-sync.html
나의 경우엔 후자의 경우였다.
Call SP Query를 사용했는데, 해당 SP에서 SELECT 한만큼 함수호출을 빼먹었고, 그로 인해 그 뒤에 호출된 SP들은 전부 실패했다.
삽질을 한 30분 넘게 한거 같다.
C용 mysql 라이브러리 이용해서 Manager 만들면서 시행착오 겪었던 것 정리 (추후 업데이트 할지도??) ( Connection을 계속 유지한다는 가정 하에!! )
1. PROCEDURE 호출 시 주의사항!!!
다음과 같은 상황에서 발생합니다 Multiple Statement 옵션 ( CLIENT_MULTI_STATEMENTS ) 을 지정한 상태에서 아래와 같은 프로시져를 호출한다
CALL MY_PROCEDURE( @pRETVAL ); SELECT @pRETVAL;
MY_PROCEDURE는 내부적으로 업데이트를 처리한 후 pRETVAL에 결과 값을 저장한다.
이 때 실질적으로 Result Set은 SELECT @pRETVAL; 하나만 존재하기 때문에 바로 mysql_store_result() 를 통해서 Result Set을 가져오려고 시도를 하는데 이 경우 mysql_store_result() 함수는 NULL을 리턴한다 (Result Set이 없다고 리턴!!)
mysql_error() 도 성공으로 뜬다
이 경우 Statement는 총 2개가 된다
프로시져 내부적으로 Result Set을 갖는 구문 (SELECT)가 없다 하더라도 프로시져 호출 자체적으로 비어있는 Result Set을 하나 가지고 있다.
따라서 SELECT @pRETVAL; 에 대한 Result Set을 가져오려면 mysql_next_result() 로 프로시져 Call 에 대한 빈 Result Set을 무시하고 다음 Result Set을 가져와야 한다
만일 MY_PROCEDURE 안에 SELECT문이 있다면?
SELECT 문의 수 + 1 만큼의 mysql_next_result() 호출이 있어야 한다
+1 이 바로 프로시져 Call 에 의한 빈 Result Set
!!!여기서 중요하게 생각해야 하는 부분이 하나 더 있습니다!!! 그렇다면 그냥 PROCEDURE() 만 호출해 봅시다
CALL MY_PROCEDURE();
이 경우에 만약 mysql_next_result() 처리를 하지 않으면 어떻게 될까요?
라이브러리 단에서 fetch 해야 할 result set이 남아있다는 판단 하에... out of sync 에러를 던져버립니다!!!
mysql_ping() 도 out of sync 에러를 던져버리기 때문에 sql 실행 전에 접속 체크를 위해서 mysql_ping() 쳐보면 에러 떨어집니다.
주의하고 또 주의합시다!!!
'DB > MYSQL' 카테고리의 다른 글
paging 작업 (0) | 2021.10.07 |
---|---|
[펌] MyISAM와 InnoDB 비교 (0) | 2021.10.07 |
MYSQL을 위한 GUI 툴 (0) | 2021.10.05 |
Insert 할 때 value 조건문 걸기 (0) | 2021.10.05 |
시간 관련 함수 (0) | 2021.10.05 |