'MySQL'에 해당되는 글 1건

  1. 2012.03.18 [번역] MySQL C-API (메뉴얼 chap.18)


첫번째 회사에서 1998년인가 1999년인가에 MySQL 기반으로 전자 지불 Gateway 서비스를 구현하여 실제 서비스를 했던 적이 있었다. 
당시에 인연이 많았던 이니시스의 PG (Payment Gateway)에서 제공하는 TX API로 구현한 페이지가 각 고객의 지불 단계에서 불려지도록 하는 서비스였고, 나름 페이지 내에 고객사별로 customizing이 가능했었고 실제 이를 통한 트랜잭션이 꽤 많이 났었던 서비스였다.

당시 MySQL을 공부하면서 서비스를 구현하였는데, 성격 상 공부하면서 한글로 번역을 하게 되었고 기왕 한김에 역시 나름의 의무감에 KLDP에 번역본을 제공하여 문태준님의 다른 번역 부분과 함께 공식적으로 KLDP 의 MySQL 메뉴얼 번역본으로 제공되고 있다. 
얼마나 많은 분들이 이 번역본을 보셨을지는 모르겠지만 그래도 한글 자료가 부족했던 90년대 말에 MySQL로 고생하시는 개발자들에게 조금이나마 보탬이 될 수 있었을려나 하는 생각을 해본다. 

========================================================================================================
 
18 MySQL client tools and APIs

18.1 MySQL C API

C API 코드는 MYSQL에 함께 배포되며, 이것은 mysqlclient 라이브러리에 포함되어져 C 프로그램으로 하여금 데이터베이스에 접근할 수 있도록 해준다. MySQL 소스 배포판의 많은 클라이언트들이 C로 코딩되어 있으며, C API를 사용하는 방법에 대한 설명을 찾고자 할 때 이 클라이언트들의 코드를 참조할 수 있다.
18.2 C API datatypes
-----------------------------------------------------------------------------------------
|데이터 형식	      | 설명								|
-----------------------------------------------------------------------------------------
|  MYSQL	      | 데이터 베이스와의 하나의 연결을 다루는 구조체로서 거의 모든     |
|		      | MySQL 함수들에서 사용된다.					|
-----------------------------------------------------------------------------------------
|  MYSQL_RES	      | 행을 리턴하는 질의들(SELECT, SHOW, DESCRIBE, EXPLAIN)의 결	|
|		      | 과를 표현하는 구조체로서 어떤 질의의 결과로서 리턴되는 정보들   |
|		      | 을 결과 셋(result set)이라고 부른다.				|
-----------------------------------------------------------------------------------------
|  MYSQL_ROW	      | 한 행의 데이터를 표현하는 데이터 형식이다. 현재 이것은 counted  |
|		      | byte string들의 배열로 구현되어 있다. 필드값이 이진 데이터를 포 |
|		      | 함할 수 있는 경우에는 값 내부에 null 바이트를 가지고 있을 수    |
|		      | 있기 때문에 이 데이터 형식을 null-terminated string으로 다룰 수 |
|		      | 없다. 행들은 mysql_fetch_row() 함수를 호출함으로써 얻어올 수 있 |
|		      | 다.								|
-----------------------------------------------------------------------------------------
|  MYSQL_FIELD	      | 필드 명, 형식, 크기와 같은 필드에 대한 정보를 포함하는 구조체	|
|		      | 이다. 이 구조체의 멤버들은 아래에서 상세히 기술된다. 각각의 필  |
|		      | 드에 대하여 mysql_fetch_field() 함수를 호출함으로써 각 필드에 대|
|		      | 한 MYSQL_FIELD 구조체의 값을 얻을 수 있다. 필드에 들어있는      |  
|		      | 실제 값은 이 구조체의 멤버가 아니며, 실제 데이터는 		|
|		      | MYSQL_ROW 구조체에 들어가게 된다.				|
-----------------------------------------------------------------------------------------
|  MYSQL_FIELD_OFFSET | MySQL 필드 리스트에 들어가는 변위(offset)을 표현하는 type-safe  |
|		      | 형식이다(mysql_field_seek() 함수에서 사용된다). Offset은 행 내에|
|		      | 서의 필드의 개수이며 0에서 시작한다. 				|
-----------------------------------------------------------------------------------------
|  my_ulonglong	      | 행들의 개수, mysql_affected_rows(), mysql_num_rows(), 		|
|		      | mysql_insert_id() 함수에서 사용되는 형식이다. 이 형식은 0에서   |
|		      | 1.84e19까지의 값을 가질 수 있다. 어떤 시스템에서는 		|
|		      | my_ulonglong 형식의 값을 출력하는데 문제가 있을 수 있는데, 이   |
|		      | 경우에 이 값을 출력하기 위해서는 이것을 unsigned long 형식으로  |
|	      	      | 변환한 후 '%lu' 프린트 형식을 사용한다. 예를 들면 다음과 같다:  |
|		      |									|	
|		      | printf (Number of rows: %lu\n", (unsigned long) \		|
|		      | mysql_num_rows(result));					|
-----------------------------------------------------------------------------------------

MYSQL_FIELD 구조체는 다음과 같은 멤버들을 가진다:

char * name 
	- 필드의 이름

char * table
	- 이 필드가 계산된 필드(calculated field)가 아닌 경우, 이 필드를 가지고 있는 
	  테이블의 이름. 계산된 필드인 경우 NULL 포인터를 가진다

char * def
	- 이 필드의 디폴트 값(mysql_list_fields() 함수를 사용하는 경우에만 설정된다)

enum enum_field_types type
	- 필드의 형식(type). 필드 형식은 다음 테이블 값 중에 하나이다.

-------------------------------------------------------------------------
| Type value		| Type meaning					|
-------------------------------------------------------------------------
| FIELD_TYPE_TINY	| TINYINT field					|
-------------------------------------------------------------------------
| FIELD_TYPE_SHORT	| SMALLINT field				|
-------------------------------------------------------------------------
| FIELD_TYPE_LONG	| INTEGER field					|
-------------------------------------------------------------------------
| FIELD_TYPE_INT24	| MEDIUMINT field				|
-------------------------------------------------------------------------
| FIELD_TYPE_LONGLONG	| BIGINT field					|
-------------------------------------------------------------------------
| FIELD_TYPE_DECIMAL	| DECIMAL or NUMERIC field			|
-------------------------------------------------------------------------
| FIELD_TYPE_FLOAT	| FLOAT field					|
-------------------------------------------------------------------------
| FIELD_TYPE_DOUBLE	| DOUBLE or REAL field				|
-------------------------------------------------------------------------
| FIELD_TYPE_TIMESTAMP	| TIMESTAMP field				|
-------------------------------------------------------------------------
| FIELD_TYPE_DATE	| DATE field					|
-------------------------------------------------------------------------
| FIELD_TYPE_TIME	| TIME field					|
-------------------------------------------------------------------------
| FIELD_TYPE_DATETIME	| DATETIME field				|
-------------------------------------------------------------------------
| FIELD_TYPE_YEAR	| YEAR field					|
-------------------------------------------------------------------------
| FIELD_TYPE_STRING	| String (CHAR or VARCHAR) field		|
-------------------------------------------------------------------------
| FIELD_TYPE_BLOB	| BLOB or TEXT field (use max_length to 	|
|			| determine the maximum length)			|
-------------------------------------------------------------------------
| FIELD_TYPE_SET	| SET field					|
-------------------------------------------------------------------------
| FIELD_TYPE_ENUM	| ENUM field					|
-------------------------------------------------------------------------
| FIELD_TYPE_NULL	| NULL-type field				|
-------------------------------------------------------------------------
| FIELD_TYPE_CHAR	| Deprecated: use FIELD_TYPE_TINY instead   	|
-------------------------------------------------------------------------

IS_NUM() 매크로(macro)를 이용하여 필드가 정수형(numeric type)인가를 테스트할 수 있다. 
IS_NUM()에 형식값(type value)를 인수로 넘겼을 때 필드가 정수형이면 'TRUE'를 리턴한다:

if (IS_NUM(field->type)) {
    printf("Field is numeric\n");
}

unsigned int length 
	- 필드의 길이(width)

unsigned int max_length 
	- 결과 셋에 대한 필드의 최대 길이(maximum width). mysql_list_fields() 함수를 
	  사용하는 경우 이 멤버에는 필드의 최대 길이가 저장된다.

unsigned int flags 
	- 필드에 대한 Different bit-flags. 플래그 값은 0 혹은 다음의 비트 셋(bit set) 중에 
	  하나이다.

-----------------------------------------------------------------
|  플래그 값  		|	의미				|
-----------------------------------------------------------------
|  NOT_NULL_FLAG	| Field can't be NULL			|
-----------------------------------------------------------------
|  PRI_KEY_FLAG		| Field is part of a primary key	|
-----------------------------------------------------------------
|  UNIQUE_KEY_FLAG	| Field is part of a unique key		|
-----------------------------------------------------------------
|  MULTIPLE_KEY_FLAG	| Field is part of a key		|
-----------------------------------------------------------------
|  UNSIGNED_FLAG	| Field has the UNSIGNED attribute	|
-----------------------------------------------------------------
|  ZEROFILL_FLAG	| Field has the ZEROFILL attribute	|
-----------------------------------------------------------------
|  BINARY_FLAG		| Field has the BINARY attribute	|
-----------------------------------------------------------------
|  AUTO_INCREMENT_FLAG	| Field has the AUTO_INCREMENT attribute|
-----------------------------------------------------------------
|  ENUM_FLAG		| Field is an ENUM (deprecated)		|
-----------------------------------------------------------------
|  BLOB_FLAG		| Field is a BLOB or TEXT (deprecated)	|
-----------------------------------------------------------------
|  TIMESTAMP_FLAG	| Field is a TIMESTAMP (deprecated)	|
-----------------------------------------------------------------

BLOB_FLAG, ENUM_FLAG, TIMESTAMP_FLAG 플래그들은 이들 플래그들이 자신의 형식(type)의 속성을 표시하기 보다는 필드의 형식을 표시하기 때문에 이 플래그들을 사용하는 것은 좋지 않다. 그 대신 'field->type' 값을 FIELD_TYPE_BLOB, FIELD_TYPE_ENUM, 혹은 FIELD_TYPE_TIMESTAMP과 비교하는 것이 좋다. 아래의 예제는 플래그 값들의 전형적인 사용법에 대하여 설명한다:

if (field->flags & NOT_NULL_FLAG) {
    printf("Field can't be null\n");
}

플래그 값의 불리언 상태(boolean status)를 결정하는데 다음과 같은 매크로(macro)들을 사용할 수 있다:

	IS_NOT_NULL(flags)	이 필드가 'NOT NULL'로 정의되어 있으면 참
	IS_PRI_KEY(flags)	이 필드가 primary key인 경우에 참
	IS_BLOB(flags)		이 필드가 BLOB이나 TEXT인 경우에 참

unsigned int decimals 
	- 정수형 필드(numeric field)인 경우 자리수(number of decimal)


18.3 C API function overview
	
-------------------------------------------------------------------------------------------------
| Function			|	Description						|
-------------------------------------------------------------------------------------------------
| mysql_affected_rows()		| 가장 최근의 UPDATE, DELETE, INSERT 질의에 의한 결과 		|
|				| 행의 개수 를 리턴한다.					|
-------------------------------------------------------------------------------------------------
| mysql_close()			| 서버와의 연결을 종료한다.					|
-------------------------------------------------------------------------------------------------
| mysql_connect()		| 서버와 연결하며 이 함수를 사용하기보다는 			|
-------------------------------------------------------------------------------------------------
|				|  mysql_real_connect() 함수를 사용하는 것이 권장된다.		|
| mysql_create_db()		| DB를 생성한다. 이 함수를 사용하기보다는 SQL 명령어인 		|
|				| CREATE DATABASE 문을 사용하는 것이 좋다.			|
-------------------------------------------------------------------------------------------------
| mysql_data_seek()		| 질의 결과 셋에서 임의의 행을 찾는다.				|
-------------------------------------------------------------------------------------------------
| mysql_debug()			| 주어진 문자열로 DBUG_PUSH를 수행한다.				|
-------------------------------------------------------------------------------------------------
| mysql_drop_db()		| DB를 드롭한다. 이 함수를 사용하기보다는 SQL 명령어인 DROP 	|
|				| DATABASE 문을 사용하는 것이 좋다.				|
-------------------------------------------------------------------------------------------------
| mysql_dump_debug_info()	| 서버로 하여금 디버깅 정보를 로그에 남기도록 한다.		|
-------------------------------------------------------------------------------------------------
| mysql_eof()			| 결과셋의 마지막 행이 읽혀졌는가를 표시한다. 이 함수를		|
|				| 사용하기보다는 mysql_errno()나 mysql_error()함수가 사용된다.	|
-------------------------------------------------------------------------------------------------
| mysql_errno()			| 가장 최근에 수행된 MySQL 함수에 대한 에러넘버를 리턴한다.	|
-------------------------------------------------------------------------------------------------
| mysql_error()			| 가장 최근에 수행된 MySQL 함수에 대한 에러메세지를 리턴한다.	|
-------------------------------------------------------------------------------------------------
| mysql_escape_string()		| SQL 문 내부의 특수 문자를 처리한다. 				|
-------------------------------------------------------------------------------------------------
| mysql_fetch_field()		| 테이블의 다음 필드의 형식(type)을 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_fetch_field_direct()	| 주어진 필드 번호에 대한 필드 형식을 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_fetch_fields()		| 모든 필드 구조에 대한 배열을 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_fetch_lengths()		| 현재 행의 모든 컬럼들의 길이를 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_fetch_row()		| 결과셋으로부터 다음 행을 가져온다.				|
-------------------------------------------------------------------------------------------------
| mysql_field_seek()		| 컬럼커서를 특정 컬럼으로 놓는다.				|
-------------------------------------------------------------------------------------------------
| mysql_free_result()		| 결과셋에 의해 사용된 메모리를 해제한다.			|
-------------------------------------------------------------------------------------------------
| mysql_get_client_info()	| 클라이언트의 버전 정보를 리턴한다.				|
-------------------------------------------------------------------------------------------------
| mysql_get_host_info()		| 현재 연결에 대한 정보를 가진 문자열을 리턴한다.		|
-------------------------------------------------------------------------------------------------
| mysql_get_proto_info()	| 연결에 사용된 프로토콜 버전을 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_get_server_info()	| 서버의 버전 넘버를 리턴한다.					|
-------------------------------------------------------------------------------------------------
| mysql_info()			| 가장 최근에 수행된 질의에 대한 정보를 리턴한다.		|
-------------------------------------------------------------------------------------------------
| mysql_init()			| MYSQL 구조체를 생성하거나 초기화한다.				|
-------------------------------------------------------------------------------------------------
| mysql_insert_id()		| AUTO_INCREMENT 필드에 대하여 가장 최근에 생성된 ID를 리턴.	|
-------------------------------------------------------------------------------------------------
| mysql_list_dbs()		| 간단한 정규식에 의해 매칭되는 DB 이름들을 리턴한다.		|
-------------------------------------------------------------------------------------------------
| mysql_list_fields()		| 간단한 정규식에 의해 매칭되는 필드 이름들을 리턴한다.		|
-------------------------------------------------------------------------------------------------
| mysql_list_processes()	| 현재 서버의 쓰레드들의 리스트를 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_list_tables()		| 간단한 정규식에 의해 매칭되는 테이블 이름들을 리턴한다.	|
-------------------------------------------------------------------------------------------------
| mysql_num_fields()		| 결과셋 내의 컬럼 개수를 리턴한다.				|
-------------------------------------------------------------------------------------------------
| mysql_num_rows()		| 결과셋 내의 행 개수를 리턴한다.				|
-------------------------------------------------------------------------------------------------
| mysql_ping()			| 서버와의 연결이 제대로 수행되고 있나를 체크하며, 필요하면 	|
|				| 서버와 재연결한다.						|
-------------------------------------------------------------------------------------------------
| mysql_query()			| Null terminated 문자열로 주어지는 SQL 질의를 수행한다.	|
-------------------------------------------------------------------------------------------------
| mysql_real_connect()		| MySQL 서버와 연결한다.					|
-------------------------------------------------------------------------------------------------
| mysql_real_query()		| Counted 문자열로 주어진 SQL 질의를 수행한다.			|
-------------------------------------------------------------------------------------------------
| mysql_reload()		| 서버로 하여금 grant 테이블을 다시 리로드하게 한다.		|
-------------------------------------------------------------------------------------------------
| mysql_row_seek()		| mysql_row_tell() 함수가 리턴한 값을 가지고 결과셋 내의 한 	|
|				| 행을 찾는다.							|
-------------------------------------------------------------------------------------------------
| mysql_row_tell()		| Row cursor 위치를 리턴한다.					|
-------------------------------------------------------------------------------------------------
| mysql_select_db()		| 특정 DB에 연결한다.						|
-------------------------------------------------------------------------------------------------
| mysql_shutdown()		| DB 서버를 셧다운시킨다.					|
-------------------------------------------------------------------------------------------------
| mysql_stat()			| 서버의 상태를 표시하는 문자열을 리턴한다.			|
-------------------------------------------------------------------------------------------------
| mysql_store_result()		| 전체 결과셋을 클라이언트로 가져온다.				|
-------------------------------------------------------------------------------------------------
| mysql_thread_id()		| 현재 쓰레드의 ID를 리턴한다.					|
-------------------------------------------------------------------------------------------------
| mysql_use_result()		| 행단위로 데이터를 넘겨받기 위한 결과 셋을 초기화한다.		|
-------------------------------------------------------------------------------------------------

서버에 연결할 때는 먼저 mysql_init() 함수를 호출함으로써 connection handler를 초기화한 후, 그 handler와 hostname, user name, password와 같은 다른 정보들을 가지고 mysql_real_connect() 함수를 호출한다. 모든 작업이 끝나면 mysql_close() 함수를 호출함으로써 연결을 종료한다.

연결이 이루어져 있는 동안 클라이언트는 mysql_query()나 mysql_real_query() 함수를 이용하여 서버에 SQL 질의를 보낼 수 있다. mysql_query()는 질의가 null-terminated string이어야 하며, mysql_real_query()는 counted string이어야 한다. 만약 string이 바이너리 데이터(중간에 NULL 바이트를 가질 수도 있는)인 경우에는 반드시 mysql_real_query()를 사용하여야 한다.

SELECT 질의가 아닌 질의(INSERT, UPDATE, DELETE)에 대해서는 mysql_affected_row() 함수를 호출함으로써 얼마나 많은 행이 affect되어졌나를 알 수 있다.

SELECT 질의의 경우, select되어진 행들을 결과셋(result set)으로 얻게 된다(SHOW, DESCRIBE, EXPLAIN과 같은 문은 행을 리턴하는 것에 있어서 SELECT와 비슷하며, 이들은 SELECT 문과 동일하게 처리되어야 한다)

클라이언트가 결과셋을 처리하는 방법에는 두가지가 있다. 하나는 mysql_store_result() 함수를 호출함으로써 전체 결과 셋을 한번에 얻어오는 것으로써, 이 함수는 질의에 의해 리턴된 모든 행들을 서버로부터 얻어내어 클라이언트에 저장한다. 두번째는 mysql_use_result() 함수를 호출함으로써 클라이언트가 행별로 결과셋을 얻어오는 것이다. 이 함수는 행을 얻어오기 위한 작업을 초기화하기만 하며 실제로 서버로부터 행을 가져오지는 않는다.

위 두가지 경우 모두, mysql_fetch_row() 함수를 호출함으로써 행들에 접근하게 된다. 
mysql_store_result()의 경우 mysql_fetch_row()는 서버로부터 이미 fetch된 행들에 접근하며, mysql_use_result()의 경우, mysql_fetch_row()는 실제로 서버로부터 행들을 얻어온다. 각 행의 데이터 값의 크기에 대한 정보는 mysql_fetch_lengths() 함수를 호출함으로써 얻을 수 있다. 결과 셋을 이용한 작업이 끝나면 mysql_free_result()를 호출함으로써 결과 셋을 위해 사용된 메모리를 해제한다. 이 두가지 retrieval 체계는 상호 보완적이다. 클라이언트 프로그램은 각각의 요구에 따라 적절한 접근 방법을 선택하여야 한다. 실질적으로는 mysql_store_result()가 주로 사용된다. mysql_store_result()의 이점은 행들이 클라이언트로 fetch된 이후에는 클라이언트가 행들에 순차적으로 접근할 수 있을 뿐만 아니라 mysql_data_seek()나 mysql_row_seek()를 이용하여 결과 셋 안에서 현행 위치(current row position)를 변경함으로써 결과 셋 내에서 앞뒤로 움직일 수 있다는 것이다. 또한 mysql_num_rows()를 호출함으로써 얼마나 많은 행들이 있나를 알 수도 있다. 다른 한편으로, mysql_store_result()를 위해 요구되는 메모리가 많기 때문에 out-of-memory 상태를 만날 가능성이 많다. mysql_use_result()의 이점은 한번에 하나의 행만을 관리하기 때문에 결과 셋을 위한 메모리가 적게 필요하다는 것이며 또한 더 적은 메모리 할당 부하로 인하여 더 속도가 빠를 수 있다. 단점은 서버를 tying up하는 것을 피하기 위하여 각 행을 빠르게 처리해주어야 하며 결과 셋 내에서 랜덤하게 행들에 접근할 수 없고 단지 순차적으로만 접근할 수 있다. 또한 모든 행들을 받기 전에는 결과 셋 내에 얼마나 많은 행들이 있나를 알 수가 없다. 결과 셋 중간에 찾고자 하는 정보를 찾았더라도 모든 행을 끝까지 받고 있어야 한다. API를 이용함으로써 질의가 SELECT인가 아닌가를 모른 상태에서도 클라이언트가 질의에 적절히 대응할 수 있게 할 수 있는데, 이는 mysql_query() (혹은 mysql_real_query())를 호출한 후에 mysql_store_result()를 호출함으로써 가능하다. 만약 결과 셋이 성공(succeed)이면 질의가 SELECT이며 행들을 읽을 수 있다. 만약 실패이면 mysql_num_fields()를 호출하여 result가 정말로 기대되어지는가를 결정할 수 있으며, mysql_num_fields()가 0을 리턴하면 질의는 아무 데이터도 리턴하지 않는다(이것은 질의가 INSERT, UPDATE, DELETE 등임을 의미한다). 만약 mysql_num_fields()가 0이 아니면 질의는 반드시 행을 리턴하여야 하는데 리턴하지 않았음을 의미하며, 이는 질의가 SELECT였으며 수행에 실패하였음을 알려준다. mysql_store_result()과 mysql_use_result()은 결과 셋을 구성하는 필드들에 대한 정보(필드의 개수, 이름, 형식 등)를 얻을 수 있게 해준다. mysql_fetch_field()를 각각 호출하여 행 내에서의 필드 정보를 순차적으로 접근하거나, mysql_fetch_field_direct()를 호출함으로써 얻은 행 내의 필드 번호를 통하여 접근할 수 있다. 현쟁의 필드 커서 위치(current field cursor position)는 mysql_field_seek() 함수를 호출함으로써 변경될 수 있다. Setting the field cursor affects subsequent calls to mysql_fetch_field(). 또한 mysql_fetch_fields()를 호출함으로써 한꺼번에 모든 필드 정보를 얻을 수도 있다. 에러를 찾고 리포팅하기 위해서 MySQL은 mysql_errno()와 mysql_error() 함수를 통하여 에러 정보에 접근할 수 있게 해준다. 이 두 함수는 가장 최근에 invoke된 성공하거나 실패할 수 있는 함수에 대한 에러 코드 혹은 에러 메시지를 리턴하며, 이를 통하여 언제 에러가 발생하고 그것이 무엇인가를 알 수 있다. 18.4 C API function descriptions 아래의 함수 설명에 있어서 NULL로 표시한 인수나 리턴값은 C 프로그래밍 언어에서의 NULL의 의미이며, MySQL에서의 NULL 값을 의미하는 것이 아니다. 어떤 값을 리턴하는 함수들은 보통 포인터나 정수를 리턴한다. 만약 별 다른 표시가 없다면 포인터를 리턴하는 함수들은 성공하였을 때 NULL이 아닌 값을, 에러를 표시하기 위해서는 NULL 값을 리턴한다. 정수를 리턴하는 함수의 경우에는 성공하였을 경우 0을, 에러인 경우에는 0이 아닌 값을 리턴한다. 함수가 에러를 리턴한 경우에는 mysql_errno(), mysql_error() 함수를 이용하여 에러를 체크할 수 있다. 18.4.1 mysql_affected_rows() my_ulonglong mysql_affected_rows(MYSQL *mysql) 18.4.1.1 Description 마지막으로 수행된 UPDATE, DELETE, INSERT 질의에 의한 행의 수를 리턴하며, 주로 UPDATE, DELETE, INSERT 문에 대한 mysql_query() 함수가 호출된 후 즉시 호출된다.
SELECT 문의 경우 mysql_affected_rows() 함수는 mysql_num_row() 함수처럼 동작한다. mysql_affected_rows() 함수는 현재 매크로(macro)로 구현되어 있다. 18.4.1.2 Return values 0보다 큰 정수는 affected되거나 retrieved된 행의 수를 의미한다. 0은 WHERE 조건에 합당하는 레코드가 없거나 아무 질의도 아직 수행되지 않았음을 의미한다. -1은 질의가 에러를 리턴하였거나 혹은 SELECT 질의인 경우 mysql_affected_rows() 함수가 mysql_store_result() 함수의 호출 이전에 호출되었음을 의미한다. 18.4.1.3 Errors 없음. 18.4.1.4 Example mysql_query(&mysql,"UPDATE products SET cost=cost*1.25 WHERE group=10"); printf("%d products updated",mysql_affected_rows(&mysql)); 18.4.2 mysql_close() void mysql_close(MYSQL *mysql) 18.4.2.1 Description 현재 열려있는 서버와의 연결을 끊는다. 만약 연결 핸들(connection handle)이 mysql_init()이나 mysql_real_connect()에 의해서 자동으로 할당되었다면 mysql_close()는 mysql에 의해 지정된 연결 핸들을 deallocation한다. 18.4.2.2 Return values 없음. 18.4.2.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.3 mysql_connect() MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd) 18.4.3.1 Description 이 함수를 사용하는 것은 권장되지 않으며, 대신 mysql_real_connect() 함수가 주로 사용된다. mysql_connect() 함수는 호스트에서 돌아가고 있는 MySQL DB 엔진과의 연결을 시도한다. Mysql_connect()는 mysql_get_client_info() 함수를 제외한 다른 모든 API 함수를 수행하기 이전에 반드시 성공적으로 수행되어져야 한다. 함수의 인수들이 가지는 의미는 mysql_real_connect() 함수와 동일하다. 18.4.3.2 Return values mysql_real_connect() 함수와 동일. 18.4.3.3 Errors mysql_real_connect() 함수와 동일. 18.4.4 mysql_create_db() int mysql_create_db(MYSQL *mysql, const char *db) 18.4.4.1 Description 'db' 인수로 주어진 이름의 데이터베이스를 생성한다. 이 함수를 사용하는 것은 권장되지 않으며, 대신 'CREATE DATABASE'와 같은 SQL 문을 mysql_query() 함수를 이용하여 수행하는 것이 좋다. 18.4.4.2 Return values 데이터베이스가 성공적으로 생성된 경우 0, 에러가 발생한 경우 0이 아닌 값을 리턴한다. 18.4.4.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.4.4 Example if(mysql_create_db(&mysql, "my_database")) { fprintf(stderr, "Failed to create new database. Error: %s\n", mysql_error(&mysql)); } 18.4.5 mysql_data_seek() void mysql_data_seek(MYSQL_RES *result, unsigned int offset) 18.4.5.1 Description 결과 셋 내에서 임의의 행을 찾는다. 이를 위해서는 결과 셋 구조체가 질의에 의한 전체 결과를 포함하고 있어야 하며, 따라서 mysql_data_seek() 함수는 mysql_use_result() 함수와는 사용할 수 없고 mysql_store_result() 함수와 사용한다. Offset 인수는 0에서 mysql_num_rows(result)-1 사이의 값을 가져야 한다. 18.4.5.2 Return values None. 18.4.5.3 Errors None. 18.4.6 mysql_debug() void mysql_debug(char *debug) 18.4.6.1 Description debug 인수로 주어진 문자열을 가지고 DBUG_PUSH를 수행한다. mysql_debug() 함수는 Fred Fish debug 라이브러리를 사용한다. 이 함수를 사용하기 위해서는 반드시 클라이언트 라이브러리를 디버깅을 지원하도록 컴파일하여야 한다. 19.10 절에서 MySQL 서버의 디버깅에 대하여 논의하며, 19.11절에서 MySQL 클라이언트의 디버깅에 대하여 논의한다. 18.4.6.2 Return values None. 18.4.6.3 Errors None. 18.4.6.4 Example 아래와 같은 호출은 클라이언트 라이브러리로 하여금 클라이언트의에 '/tmp/client.trace' 파일에 trace file을 생성하게 해준다: mysql_debug("d:t:O,/tmp/client.trace"); 18.4.7 mysql_drop_db() int mysql_drop_db(MYSQL *mysql, const char *db) 18.4.7.1 Description db 인수로 주어진 이름의 데이터베이스를 드롭시킨다. 이 함수를 사용하는 것은 권장되지 않으며, 대신 'DROP DATABASE'와 같은 SQL 문을 mysql_query() 함수를 이용하여 수행하는 것이 좋다. 18.4.7.2 Return values 데이터베이스가 성공적으로 드롭된 경우 0을, 에러가 발생한 경우 0이 아닌 값을 리턴한다. 18.4.7.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.7.4 Example if(mysql_drop_db(&mysql, "my_database")) fprintf(stderr, "Failed to drop the database: Error: %s\n", mysql_error(&mysql)); 18.4.8 mysql_dump_debug_info() int mysql_dump_debug_info(MYSQL *mysql) 18.4.8.1 Description 서버로 하여금 로그에 디버깅 정보를 기록하게 한다. 연결되어 있는 사용자(connected user)는 이 작업을 위한 권한을 가지고 있어야 한다. 18.4.8.2 Return values 명령이 성공하면 0, 에러가 발생하면 0이 아닌 값을 리턴한다. 18.4.8.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.9 mysql_eof() my_bool mysql_eof(MYSQL_RES *result) 18.4.9.1 Description 이 함수를 사용하는 것은 권장되지 않으며, 대신 mysql_errno() 함수나 mysql_error() 함수를 사용한다. mysql_eof() 함수는 결과 셋의 마지막 행이 읽혀졌나를 판단한다. mysql_store_result() 함수로부터 성공적으로 결과 셋을 얻었다면 클라이언트는 한번의 작업으로 전체 셋을 얻게된다. 이 경우 mysql_fetch_row() 함수로부터 리턴되는 NULL은 항상 결과 셋의 마지막에 도달하였음을 의미하게 되며 mysql_eof() 함수를 호출할 필요가 없다. 한편으로 mysql_use_result() 함수를 사용하여 결과 셋을 얻었다면 셋의 행들은 mysql_fetch_row() 함수를 호출할 때마다 서버로부터 하나씩 얻어진다. 이 과정 중에 연결 에러가 발생할 수 있기 때문에 myql_fetch_row() 함수가 리턴하는 NULL 값은 반드시 결과 셋의 마지막에 도달하였음을 의미한다고 볼 수 없다. 이 경우 mysql_eof() 함수를 사용하여 무엇이 일어났나를 결정할 수 있다. 이때 mysql_eof() 함수는 결과 셋의 마지막에 도달한 경우 라면 0이 아닌 값을 리턴하며, 에러인 경우에는 0을 리턴하게 된다. 표준 mySQL 에러 함수인 mysql_errno()와 mysql_error() 함수가 더 많은 정보를 제공하기 때문에 이들을 사용하는 것이 좋다… 18.4.9.2 Return values 에러이면 0을, 결과 셋의 마지막에 도달하였으면 0이 아닌 값을 리턴한다. 18.4.9.3 Errors None. 18.4.9.4 Example 다음은 mysql_eof()의 사용예를 보여준다: mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // do something with data } if(!mysql_eof(result)) // mysql_fetch_row() failed due to an error { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } However, you can achieve the same effect with the standard MySQL error functions: mysql_query(&mysql,"SELECT * FROM some_table"); result = mysql_use_result(&mysql); while((row = mysql_fetch_row(result))) { // do something with data } if(mysql_errno(&mysql)) // mysql_fetch_row() failed due to an error { fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } 18.4.10 mysql_errno() unsigned int mysql_errno(MYSQL *mysql) 18.4.10.1 Description mysql 인수에 의해 지정된 연결에 대하여 mysql_errno()는 가장 최근에 수행된 API 함수에 대한 에러 코드를 리턴한다. 0을 리턴하면 아무 에러도 발생하지 않음을 의미한다. 클라이언트 에러 메시지 넘버들은 MYSQL의 'errmsg.h' 헤더 파일에 나열되어 있으며, 서버 에러 메시지 넘버들은 'mysqld_error.h' 파일에 있다. 18.4.10.2 Return values: 에러 코드 값을 리턴. 아무 에러도 없으면 0을 리턴한다. 18.4.10.3 Errors None. 18.4.11 mysql_error() char *mysql_error(MYSQL *mysql) 18.4.11.1 Description mysql 인수에 의해 지정된 연결에 대하여 mysql_error()는 가장 최근에 수행된 API 함수에 대한 에러 메시지를 리턴한다. 비어 있는 문자열("")을 리턴하면 아무 에러도 발생하지 않음을 의미한다. 이것은 다음의 두가지 테스트가 동일함을 의미한다: if(mysql_errno(&mysql)) { // an error occurred } if(mysql_error(&mysql)[0] != '\0') { // an error occurred } 클라이언트 에러 메시지의 언어는 MySQL 클라이언트 라이브러리를 재컴파일함으로써 변경될 수 있다. 현재 몇가지 다른 언어로 된 에러 메시지를 선택할 수 있으며, 9.1 절에서는 MySQL에 의해 지원되는 언어들을 다룬다. 18.4.11.2 Return values 에러를 기술하는 문자열. 에러가 없는 경우에는 비어있는 문자열을 리턴한다. 18.4.11.3 Errors None. 18.4.12 mysql_escape_string() unsigned int mysql_escape_string(char *to, const char *from, unsigned int length) 18.4.12.1 Description from 인수에 있는 문자열을 서버로 넘겨질 escaped SQL 문으로 인코딩하여 to 인수에 넣는다. 인코딩되어지는 문자들은 NUL(ASCII 0), `\n', `\r', `\', `'' 등이다(7.1절에서는 문자열과 숫자들을 사용하는 방법에 대하여 다룬다). from 인수인 문자열은 length 인수에서 주어진 바이트 수만큼의 길이(terminating NULL을 제외한)를 가져야 한다. to 인수는 반드시 적어도 length 인수에서 주어진 길이의 2배에 1을 더한 만큼의 바이트가 할당되어야 한다. mysql_escape_string() 함수가 리턴할 때 to 인수의 내용은 null-terminated 문자열이 된다. 리턴값은 인코딩되어진 문자열의 길이이며, 이것은 terminating null 문자가 포함되지 않은 길이다. to 인수에 들어가는 문자열은 null-terminated 문자열이지만 이 문자열을 strlen() 함수나 strcpy() 함수에서 사용하여서는 안된다. 만약 from 인수로 주어진 문자열이 null을 포함하고 있다면 mysql_escape_string() 함수는 이 문자를 '\'을 앞에 붙여서 to 인수에 넣게 되며, 이것을 위의 함수들은 여전히 terminating null로 인식하게 된다. 또한 이러한 내부적인 null 바이트는 mysql_query()에 의해서 terminating null로 여겨지기 때문에 질의를 적절하게 수행할 수 없게 된다. 따라서 mysql_escape_query() 함수를 이용하여 질의를 만든 경우 mysql_query() 함수를 사용하기 보다는 mysql_real_query() 함수를 사용하는 것이 좋다. 18.4.12.2 Example char query[1000],*end; end = strmov(query, "INSERT INTO test_table values("); *end++ = '\"; end += mysql_escape_string(query,"What's this",11); *end++ = '\"; *end++ = ','; *end++ = '\"; end += mysql_escape_string(query,"binary data: \0\r\n",16); *end++ = '\"; *end++ = ')'; if (mysql_real_query(&mysql,query,(int) (end - query))) { fprintf(stderr, "Failed to insert row, Error: %s\n", mysql_error(&mysql)); } 예제에서 사용된 strmov() 함수는 mysqlclient 라이브러리에 포함되어 있으며, strcpy() 함수와 비슷하게 동작을 하지만 첫번째 인수의 terminating null에 대한 포인터를 리턴하는 것이 다르다. 18.4.12.3 Return values terminating null 문자를 제외한 to 인수에 들어간 값의 길이 18.4.12.4 Errors None. 18.4.13 mysql_fetch_field() MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result) 18.4.13.1 Description 결과 셋의 한 컬럼의 정의(definition)를 MYSQL_FIELD 구조체에 담아서 리턴한다. 결과 셋의 모든 컬럼들에 대한 정보를 얻고자 하는 경우에는 이 함수를 반복하여 호출한다. 더 이상의 필드가 남아있지 않으면 mysql_fetch_field() 함수는 NULL을 리턴한다. 새로운 SELECT 질의가 수행될 때마다 mysql_fetch_field()는 새로운 첫번째 필드에 대한 정보를 리턴하기 위해 초기화된다. mysql_fetch_field() 함수에 의해 리턴되는 필드는 또한 mysql_field_seek() 함수의 호출에 의해 영향을 받는다. SELECT 문을 수행하기 위해 msyql_query()를 호출하였지만 mysql_store_result()를 호출하지 않은 경우, mysql_fetch_field()를 호출하여 BLOB 필드의 길이를 요청하게 되면 MySQL은 디폴트 blob 길이인 8K 바이트를 리턴한다. 일단 한번 결과를 얻어오게 되면 field->max_length는 주어진 질의에 있는 컬럼의 가장 큰 값의 길이를 가지게 된다. 18.4.13.2 Return values 현재 컬럼에 대한 MYSQL_FIELD 구조체를 리턴하며, 더 이상 남은 필드가 없으면 NULL을 리턴한다. 18.4.13.3 Errors None. 18.4.13.4 Example MYSQL_FIELD *field; while((field = mysql_fetch_field(result))) { printf("field name %s\n", field->name); } 18.4.14 mysql_fetch_fields() MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result) 18.4.14.1 Description 결과 셋에 대한 모든 MYSQL_FIELD 구조체의 배열을 리턴한다. 각각의 구조체는 결과 셋 내의 각 컬럼들에 대한 필드 정의에 대한 정보를 가지고 있다. 18.4.14.2 Return values 결과 셋의 모든 컬럼들에 대한 MYSQL_FIELD 구조체의 배열 18.4.14.3 Errors None. 18.4.14.4 Example unsigned int num_fields; unsigned int i; MYSQL_FIELD *fields; num_fields = mysql_num_fields(result); fields = mysql_fetch_fields(result); for(i = 0; i < num_fields; i++) { printf("Field %u is %s\n", i, fields[i].name); } 18.4.15 mysql_fetch_field_direct() MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int fieldnr) 18.4.15.1 Description 결과 셋 내에서 fieldnr 인수로 주어진 필드 번호의 필드에 대한 필드 정의를 MYSQL_FIELD 구조체로 리턴한다. 이 함수를 이용하여 임의의 컬럼에 대한 정의를 얻어올 수 있다. fieldnr 값은 0에서 mysql_num_fields(result)-1 사이의 값을 가져야 한다. 18.4.15.2 Return values 지정된 필드에 대한 MYSQL_FIELD 구조체 18.4.15.3 Errors None. 18.4.15.4 Example unsigned int num_fields; unsigned int i; MYSQL_FIELD *field; num_fields = mysql_num_fields(result); for(i = 0; i < num_fields; i++) { field = mysql_fetch_field_direct(result, i); printf("Field %u is %s\n", i, field->name); } 18.4.16 mysql_fetch_lengths() unsigned long *mysql_fetch_lengths(MYSQL_RES *result) 18.4.16.1 Description 결과 셋 내의 현재 행의 컬럼들의 길이를 리턴한다. 만약 필드 값들을 복사하고자 하는 경우 이 길이 정보는 최적화(optimization)을 위해 유용하게 사용할 수 있다. strlen() 함수를 호출할 필요가 없기 때문이다. 특히 결과 셋이 이진 데이터를 포함하고 있는 경우에는 strlen() 함수가 NULL 문자를 포함하고 있는 필드에 대하여 잘못된 결과를 리턴할 수 있기 때문에 데이터의 크기를 결정하는데 이 함수를 사용하여야 한다. 빈 컬럼이나 NULL 값을 가지는 컬럼에 대한 길이는 0이 된다. 이 두가지 경우를 구분하는 방법은 mysql_fetch_row() 함수에 대한 설명을 참조한다. 18.4.16.2 Return values 각 컬럼(null termination character를 제외한)의 크기를 가지고 있는 unsigned long 정수형의 배열. 에러가 발생한 경우에는 NULL을 리턴한다. 18.4.16.3 Errors mysql_fetch_lengths()는 결과 셋의 현재 행에 대해서만 유효하다. mysql_fetch_row() 함수를 호출하기 전에 이 함수를 호출하거나 결과 셋 내의 모든 행들을 얻어온 후에 호출하는 경우에 NULL을 리턴한다. 18.4.16.4 Example MYSQL_ROW row; unsigned long *lengths; unsigned int num_fields; unsigned int i; row = mysql_fetch_row(result); if (row) { num_fields = mysql_num_fields(result); lengths = mysql_fetch_lengths(result); for(i = 0; i < num_fields; i++) { printf("Column %u is %lu bytes in length.\n", i, lengths[i]); } } 18.4.17 mysql_fetch_row() MYSQL_ROW mysql_fetch_row(MYSQL_RES *result) 18.4.17.1 Description 결과 셋의 다음 행을 얻어온다. mysql_store_result() 함수를 호출한 후에 사용한 경우, 더 이상 얻어올 행들이 없으면 mysql_fetch_row()는 NULL을 리턴한다. mysql_use_result() 함수를 호출한 후에 사용한 경우, 더 이상 얻어올 행들이 없거나 에러가 발생하였을 때 NULL을 리턴한다. 행 내부의 값들의 개수는 mysql_num_fields(result)에 의해 주어진다. mysql_fetch_row()의 호출에 의하여 행이 얻어졌을 때 행 내부의 값들은 row[0]부터 row[mysql_num_fields(result)-1]까지의 값들로 참조될 수 있다. 행 내부에 NULL 값이 있는 경우에는 NULL 포인터로 표시된다. 행 내부의 필드 값들의 길이들은 mysql_fetch_lengths() 함수를 호출함으로써 얻어질 수 잇다. 비어있는 필드나 NULL을 포함하는 필드들은 모두 0의 길이를 가지며, 필드 값에 대한 포인터를 체크함으로써 이 두가지 경우를 구분할 수 있다. 만약 포인터가 NULL이면 해당 필드가 NULL인 경우이며, 아니면 비어있는 필드임을 의미한다. 18.4.17.2 Return values 다음 행에 대한 MYSQL_ROW 구조체. 더 이상 얻어올 행이 없거나 에러가 발생한 경우 NULL을 리턴한다. 18.4.17.3 Errors CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.17.4 Example MYSQL_ROW row; unsigned int num_fields; unsigned int i; num_fields = mysql_num_fields(result); while ((row = mysql_fetch_row(result))) { unsigned long *lengths; lengths = mysql_fetch_lengths(result); for(i = 0; i < num_fields; i++) { printf("[%.*s] ", (int) lengths[i], row[i] ? row[i] : "NULL"); } printf("\n"); } 18.4.18 mysql_field_seek() MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset) 18.4.18.1 Description 필드 커서를 offset 인수로 주어진 위치로 설정한다. 다음 mysql_fetch_field() 함수의 호출은 해당 offset로 이동한 만큼에 해당되는 컬럼에 대한 필드 정보를 얻어오게 된다. 행의 첫부분으로 보내기 위해서는 offset을 0으로 주고 함수를 호출하면 된다. 18.4.18.2 Return values 필드 커서의 이전 값(previous value) 18.4.18.3 Errors None. 18.4.19 mysql_field_tell() MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result) 18.4.19.1 Description 마지막 mysql_fetch_field() 함수에 의해 사용된 필드 커서의 위치를 알려준다. 이 리턴값을 mysql_field_seek() 함수의 offset 인수로 사용할 수 있다. 18.4.19.2 Return values 필드 커서의 현재 변위(current offset) 18.4.19.3 Errors None. 18.4.20 mysql_free_result() void mysql_free_result(MYSQL_RES *result) 18.4.20.1 Description mysql_store_result(), mysql_use_result(), mysql_list_dbs() 등에 의한 결과셋을 위해 할당되었던 메모리를 해제한다. 결과 셋을 가지고 작업을 끝내고 나면 반드시 mysql_free_result() 함수를 호출하여 메모리를 해제해 주어야 한다. 18.4.20.2 Return values None. 18.4.20.3 Errors None. 18.4.21 mysql_get_client_info() char *mysql_get_client_info(void) 18.4.21.1 Description 클라이언트 라이브러리 버전(client library version)에 대한 정보를 표시하는 문자열을 리턴한다. 18.4.21.2 Return values MySQL client library version을 표시하는 문자열 18.4.21.3 Errors None. 18.4.22 mysql_get_host_info() char *mysql_get_host_info(MYSQL *mysql) 18.4.22.1 Description 서버 호스트 네임을 포함하는 현재 사용되고 있는 연결(connection)의 형식(type)을 기술하는 문자열을 리턴한다. 18.4.22.2 Return values 서버 호스트 네임(server host name)과 연결 형식(connection type)을 나타내는 문자열 18.4.22.3 Errors None. 18.4.23 mysql_get_proto_info() unsigned int mysql_get_proto_info(MYSQL *mysql) 18.4.23.1 Description 현재 연결에 사용되고 있는 프로토콜의 버전을 리턴한다. 18.4.23.2 Return values 현재 연결에 사용되고 있는 프로토콜 버전을 나타내는 unsigned integer 18.4.23.3 Errors None. 18.4.24 mysql_get_server_info() char *mysql_get_server_info(MYSQL *mysql) 18.4.24.1 Description 서버 버전 넘버(server version number)를 표시하는 문자열을 리턴한다. 18.4.24.2 Return values 서버 버전 넘버를 표시하는 문자열 18.4.24.3 Errors None. 18.4.25 mysql_info() char *mysql_info(MYSQL *mysql) 18.4.25.1 Description 가장 최근에 수행된 질읭 peogks 정보를 제공하는 문자열을 리턴한다. 문자열의 형식(format)은 질의의 타입에 따라 달라지며, 아래와 같다. 문자열은 질의에 대한 적절한 값들을 포함하게 된다. INSERT INTO ... SELECT ... String format: Records: 100 Duplicates: 0 Warnings: 0 INSERT INTO ... VALUES (...),(...),(...)... String format: Records: 3 Duplicates: 0 Warnings: 0 LOAD DATA INFILE ... String format: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 ALTER TABLE String format: Records: 3 Duplicates: 0 Warnings: 0 18.4.25.2 Return values 가장 최근에 수행된 질의에 대한 부가적인 정보를 표현하는 문장열. 해당 질의에 대하여 아무런 정보도 얻을 수 없는 경우 NULL을 리턴한다. 18.4.25.3 Errors None. 18.4.26 mysql_init() MYSQL *mysql_init(MYSQL *mysql) 18.4.26.1 Description mysql_real_connect() 함수를 위한 MYSQL 객체를 할당(allocate)하거나 초기화(initialize)한다. 만약 mysql 인수가 NULL 포인터이면 mysql_init() 함수는 새로운 객체를 할당, 초기화하여 그 객체를 리턴한다. NULL 포인터가 아니면 객체는 초기화된 후 객체의 주소가 리턴된다.
만약 mysql_init() 함수가 새로운 객체를 할당하게 되면 그 객체는 연결을 닫기 위해 mysql_close() 함수가 호출될 때 해제되게 된다. 18.4.26.2 Return values 초기화된 MYSQL * handle. 새로운 객체를 할당하기 위한 메모리가 부족한 경우 NULL을 리턴한다. 18.4.26.3 Errors 메모리가 부족한 경우 NULL이 리턴된다. 18.4.27 mysql_insert_id() my_ulonglong mysql_insert_id(MYSQL *mysql) 18.4.27.1 Description AUTO_INCREMENT 필드에 대하여 가장 최근에 생성된 ID를 리턴한다. 이 함수는 AUTO_INCREMENT 필드를 포함하는 테이블에 INSERT 질의를 수행한 이후에 사용된다. 18.4.27.2 Return values 가장 최근에 갱신된 AUTO_INCREMENT 필드의 값 18.4.27.3 Errors None. 18.4.28 mysql_kill() int mysql_kill(MYSQL *mysql, unsigned long pid) 18.4.28.1 Description 서버로 하여금 pid 인수로 주어진 쓰레드(thread)를 죽이도록(kill) 요청한다. 18.4.28.2 Return values 성공인 경우 0을, 에러가 발생한 경우 0이 아닌 값을 리턴한다. 18.4.28.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.29 mysql_list_dbs() MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild) 18.4.29.1 Description wild 인수로 지정된 간단한 정규식(simple regular expression)에 매치되는 서버 상의 데이터베이스 이름들을 포함하고 있는 결과 셋을 리턴한다. wild 인수는 '%', '_'와 같은 와일드카드 문자를 포함할 수 있으며 모든 데이터베이스 이름을 얻고자 하는 경우 NULL을 지정할 수 있다. mysql_list_dbs() 함수를 호출하는 것은 'SHOW databases [LIKE wild]'와 같은 질의를 수행하는 것과 비슷하다. 반드시 mysql_free_result() 함수를 이용하여 결과 셋을 해제시켜 주어야 한다. 18.4.29.2 Return values 성공한 경우 MYSQL_RES 결과 셋을 리턴하며, 에러인 경우 NULL을 리턴한다. 18.4.29.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_OUT_OF_MEMORY Out of memory. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.30 mysql_list_fields() MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) 18.4.30.1 Description wild 인수로 지정된 간단한 정규식(simple regular expression)에 매치되는 테이블 상의 필드명들을 포함하고 있는 결과 셋을 리턴한다. wild 인수는 '%', '_'와 같은 와일드카드 문자를 포함할 수 있으며 모든 필드명을 얻고자 하는 경우 NULL을 지정할 수 있다. mysql_list_fields() 함수를 호출하는 것은 'SHOW fields FROM table [LIKE wild]'와 같은 질의를 수행하는 것과 비슷하다. 반드시 mysql_free_result() 함수를 이용하여 결과 셋을 해제시켜 주어야 한다. 18.4.30.2 Return values 성공한 경우 MYSQL_RES 결과 셋을 리턴하며, 에러인 경우 NULL을 리턴한다. 18.4.30.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.31 mysql_list_processes() MYSQL_RES *mysql_list_processes(MYSQL *mysql) 18.4.31.1 Description 현재의 서버 쓰레드들을 기술하는 결과 셋을 리턴한다. 이것은 'mysqladmin processlist'에 의한 결과와 동일한 정보를 보여준다. 반드시 mysql_free_result() 함수를 이용하여 결과 셋을 해제시켜 주어야 한다. 18.4.31.2 Return values 성공한 경우 MYSQL_RES 결과 셋을 리턴하며, 에러인 경우 NULL을 리턴한다. 18.4.31.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.32 mysql_list_tables() MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild) 18.4.32.1 Description wild 인수로 지정된 간단한 정규식(simple regular expression)에 매치되는 현재 데이터베이스 상의 테이블명들을 포함하고 있는 결과 셋을 리턴한다. wild 인수는 '%', '_'와 같은 와일드카드 문자를 포함할 수 있으며 모든 테이블명을 얻고자 하는 경우 NULL을 지정할 수 있다.
mysql_list_tables() 함수를 호출하는 것은 'SHOW tables [LIKE wild]'와 같은 질의를 수행하는 것과 비슷하다. 반드시 mysql_free_result() 함수를 이용하여 결과 셋을 해제시켜 주어야 한다. 18.4.32.2 Return values 성공한 경우 MYSQL_RES 결과 셋을 리턴하며, 에러인 경우 NULL을 리턴한다. 18.4.32.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.33 mysql_num_fields() unsigned int mysql_num_fields(MYSQL_RES *result) 혹은, unsigned int mysql_num_fields(MYSQL *mysql) 18.4.33.1 Description 결과 셋 내의 컬럼의 개수를 리턴한다. mysql_num_fields()를 호출할 때 결과 셋에 대한 포인터 혹은 연결 핸들을 가지고 호출할 수 있다. 만약 mysql_store_result() 함수가 NULL을 리턴한 경우(즉 결과 셋 포인터를 얻어올 수 없을 때) 연결 핸들을 사용하게 되며, 이 경우 mysql_num_fields() 함수를 호출함으로써 mysql_store_result() 함수가 비어있지 않은 결과(non-empty result)를 생성하였나의 여부를 결정할 수 있다. 이것은 클라이언트 프로그램으로 하여금 질의가 SELECT (혹은 SELECT-like) 문인가 아닌가를 알지 못하는 상태에서 적절한 행동을 취할 수 있도록 해준다. 아래에 예가 있다. 18.4.33.2 Return values 결과 셋 내의 필드 개수를 표시하는 unsigned integer. 18.4.33.3 Errors None. 18.4.33.4 Example MYSQL_RES *result; unsigned int num_fields; unsigned int num_rows; if (mysql_query(&mysql,query_string)) { // error } else { // query succeeded, process any data returned by it result = mysql_store_result(&mysql); if (result) { // there are rows num_fields = mysql_num_fields(result); // retrieve rows, then call mysql_free_result(result) } else { // mysql_store_result() returned nothing; should it have? if(mysql_num_fields(&mysql) == 0) { // query does not return data // (it was not a SELECT) num_rows = mysql_affected_rows(&mysql); } else { // mysql_store_result() should have returned data fprintf(stderr, "Error: %s\n", mysql_error(&mysql)); } } } 또 다른 대안은 mysql_num_fields(&mysql) 대신에 mysql_errno(&mysql)을 호출하는 것이다. 이 경우, 질의가 SELECT 문인가를 msyql_num_fields()의 리턴값으로 결정하기보다는 mysql_store_result()로부터의 에러를 직접 체크하게 된다. 18.4.34 mysql_num_rows() my_ulonglong mysql_num_rows(MYSQL_RES *result) 18.4.34.1 Description 결과 셋 내의 행의 개수를 리턴한다. mysql_num_rows() 함수의 사용 여부는 결과 셋을 얻기 위해서 mysql_store_result() 함수를 사용하는가 mysql_use_result() 함수를 사용하는가에 달려있다. 만약 mysql_store_result() 함수를 사용한다면 mysql_num_rows() 함수는 즉시 호출될 수 있다. 만약 mysql_use_result() 함수를 사용한다면 mysql_num_rows() 함수는 결과 셋 내의 모든 행들이 retrieve되기 이전에는 올바른 값을 리턴하지 못한다. 18.4.34.2 Return values 결과 셋 내의 행의 개수 18.4.34.3 Errors None. 18.4.35 mysql_ping() int mysql_ping(MYSQL *mysql) 18.4.35.1 Description 서버에 대한 연결이 제대로 동작하고 있나를 확인하며, 만약 연결이 끊어진 경우에는 자동으로 재연결을 시동한다. 이 함수는 클라이언트가 너무 오랫동안 쉬고 있을 때 서버가 연결을 끊었나를 체크하고 필요하다면 다시 연결하기 위해 사용될 수 있다. 18.4.35.2 Return values 서버가 살아있으면 0, 에러인 경우 0이 아닌 값을 리턴한다. 18.4.35.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.36 mysql_query() int mysql_query(MYSQL *mysql, const char *query) 18.4.36.1 Description null-terminated 문자열인 query 인수에 지정된 SQL 질의를 수행한다. 질의는 반드시 하나의 SQL 문으로 이루어져야 하며, 질의문에 세미콜론(;)이나 '\g'를 붙여서는 안된다.
mysql_query()는 이진 데이터를 포함하는 질의에는 사용할 수 없다. 이진 데이터는 중간에 NULL 문자를 포함할 수 있으며 이경우 mysql_query() 함수는 거기서 질의 문자열이 끝난 것으로 인식하기 때문에 이경우에는 mysql_real_query() 함수를 사용하여야 한다. 18.4.36.2 Return values 성공이면 0, 에러이면 0이 아닌 값을 리턴. 18.4.36.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.37 mysql_real_connect() MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket, uint client_flag) 18.4.37.1 Description mysql_real_connect() 함수는 호스트에서 돌아가고 있는 MySQL 데이터베이스 엔진에 연결을 시도한다. mysql_real_connect()는 mysql_get_client_info() 함수를 제외한 다른 모든 API 함수를 수행하기 이전에 반드시 성공적으로 수행되어져야 한다. 사용하는 인수들은 다음과 같다: mysql 인수는 MYSQL connection 구조체이거나 NULL이 될 수 있다. 만약 mysql 인수가 NULL이면 C API는 자동으로 연결 구조체를 위한 메모리를 할당하고 mysql_close()가 호출될 때 이를 해제한다. 이경우 단점은 연결이 실패한 경우 에러 메시지를 얻어올 수 없다는 것이다(mysql_errno()나 mysql_error() 함수로부터 에러 메시지를 얻기 위해서는 유효한 MYSQL 포인터를 제공하여야 한다). mysql 인수가 NULL이 아니면 이미 존재하는 MYSQL 구조체의 주소가 되어야 한다. 이 경우, mysql_real_connect() 함수를 호출하기 전에 반드시 mysql_init() 함수를 호출하여 MYSQL 구조체를 초기화해 주어야 한다. 다음의 예를 보라. host 인수는 호스트명이 되거나 IP 어드레스가 될 수 있다. 만약 host 인수가 NULL이거나 "localhost"인 경우 로컬 호스트로의 접속으로 간주된다. 만약 OS가 소켓(socket-Unix)이나 파이프(pipe-Win32)를 지원한다면 서버와의 연결을 위하여 TCP/IP 대신 이들을 사용할 수 있다. user 인수에는 사용자의 MySQL 로그인 아이디를 넣어준다. User 인수가 NULL이면 현재 사용자로 간주된다. Unix 환경에서는 현재 시스템 로그인명이 사용되며, Windows ODBC에서는 현재 사용자명이 명확히 지정되어야 한다.
15.4절에서는 ODBC 관리 프로그램에서 각 필드들을 어떻게 채울 것인가에 대하여 논의한다. passwd 인수에는 사용자에 대한 패스워드를 넣어준다. 만약 passwd가 NULL이면 user 테이블에서 패스워드 필드가 비어있는 사용자들만이 매치를 위해 체크되어진다. 이것은 데이터베이스 관리자로 하여금 데이터베이스 사용자가 자신의 패스워드를 명시하였나에 따라서 다른 권한을 가지도록 하는 MySQL 권한 시스템을 설정할 수 있도록 해준다. 주의할 것은 mysql_real_connect() 함수를 호출하기 전에 패스워드를 암호화하려고 하지 말아야 한다는 것이며, 패스워드의 암호화는 클라이언트 API에 의하여 자동으로 수행된다. db 인수는 사용할 데이터베이스의 이름을 넣어준다. 만약 db 인수가 NULL이면 디폴트 데이터베이스에 연결을 시도하게 된다. port 인수가 0이 아니면 port 인수에 명시된 포트 번호를 TCP/IP 연결을 위한 포트 번호로 사용하게 된다. host 인수가 연결의 형식을 결정한다는 것에 주의한다. unix_socket 인수가 NULL이 아니면 이 인수 문자열이 사용될 socket이나 named pipe가 된다. client_flag 값은 보통 0이지만 매우 특별한 경우에 다음의 플래그들의 조합으로 설정할 수 있다. ----------------------------------------------------------------------------------------- | Flag name | Flag meaning | ----------------------------------------------------------------------------------------- | CLIENT_FOUND_ROWS | affected row의 갯수가 아닌 found row의 갯수를 리턴한다. | ----------------------------------------------------------------------------------------- | CLIENT_NO_SCHEMA | db_name.tbl_name.col_name 형식의 문법(syntax)을 허용하지 않는다. | | | 이것은 ODBC를 위한 것으로서, 만약 이와 같은 문법을 사용하면 파서가| | | 에러를 발생시키게 된다. 이것은 ODBC 프로그램에서 버그를 찾아낼 때 | | | 유용하게 사용할 수 있다. | ----------------------------------------------------------------------------------------- | CLIENT_COMPRESS | 압축 프로토콜(compression protocol)을 사용한다. | ----------------------------------------------------------------------------------------- | CLIENT_ODBC | 클라이언트가 ODBC 클라이언트임을 알려주며, 이것은 mysqld가 좀더 | | | ODBC에 적합하도록 해준다. | ----------------------------------------------------------------------------------------- 18.4.37.2 Return values 연결이 성공하면 MYSQL * 연결 핸들(connection handle)을 리턴하며, 연결에 실패하면 NULL을 리턴한다. 연결이 성공한 경우 리턴 값은 첫번째 인수에 NULL을 지정하지 않았다면 그 인수와 동일하다. 18.4.37.3 Errors CR_CONN_HOST_ERROR MySQL 서버로의 연결에 실패 CR_CONNECTION_ERROR 로컬 MySQL 서버로의 연결에 실패 CR_IPSOCK_ERROR IP 소켓의 생성에 실패 CR_OUT_OF_MEMORY 메모리가 없음(Out of memory). CR_SOCKET_CREATE_ERROR Unix 소켓의 생성에 실패 CR_UNKNOWN_HOST 해당 호스트명에 대한 IP 주소를 찾을 수 없음. CR_VERSION_ERROR 일치하지 않는 프로토콜 버전을 사용하는 클라이언트 라이브러리를 가지고 서버에 접속 하려 시도함으로 인하여 프로토콜 불일치가 발생함. 이것은 매우 오래된 클라이언트 라이브러리를 사용하여 새로운 버전의 서버에 접속하고자 하는 경우에 발생한다. 이런 경우에는 서버를 시동할 때 '--old-protocol' 옵션을 넣어서 시동하면 해결할 수 있다. CR_NAMEDPIPEOPEN_ERROR; Win32 환경에서 named pipe를 생성하는데 실패함. CR_NAMEDPIPEWAIT_ERROR; Win32 환경에서 named pipe를 기다리는데 실패함. CR_NAMEDPIPESETSTATE_ERROR; Win32 환경에서 pipe 핸들러를 얻는데 실패함. 18.4.37.4 Example MYSQL mysql; mysql_init(&mysql); if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql)); } 18.4.38 mysql_real_query() int mysql_real_query(MYSQL *mysql, const char *query, unsigned int length) 18.4.38.1 Description query 인수에 지정된 SQL 질의를 수행하며, query 인수는 length 인수에 지정된 길이를 가져야 한다. 질의는 하나의 SQL 문으로 이루어져야 하며, 세미콜론이나 '\g'를 SQL문에 붙여서는 안된다. 이진 데이터를 포함하는 질의 데이터인 경우 mysql_query() 함수가 아닌 mysql_real_query() 함수를 사용하여야 한다. 또한 mysql_real_query()함수는 질의문의 길이를 얻기 위한 strlen() 함수를 수행하지 않기 때문에 mysql_query() 함수에 비하여 수행 속도가 빠르다. 18.4.38.2 Return values 질의에 성공하면 0, 에러가 발생하면 0이 아닌 값을 리턴한다. 18.4.38.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.39 mysql_reload() int mysql_reload(MYSQL *mysql) 18.4.39.1 Description MySQL 서버로 하여금 grant 테이블을 다시 읽도록 요청한다. 현재 연결되어 있는 사용자는 반드시 권한 설정을 다시 읽어야 한다. 이 함수를 사용하는 것은 권장되지 않으며, 대신 'FLUSH PRIVILEGES' SQL 문을 mysql_query() 함수를 이용하여 수행하는 것이 좋다. 18.4.39.2 Return values 성공하면 0, 에러면 0이 아닌 값을 리턴한다. 18.4.39.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.40 mysql_row_seek() MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *result, MYSQL_ROW_OFFSET offset) 18.4.40.1 Description 결과 셋 내에 행 커서(row cursor)를 임의의 위치로 설정한다. 이를 위해서는 결과 셋 구조체가 전체 질의 결과를 가지고 있어야 하며, 따라서 mysql_row_seek() 함수는 mysql_use_result() 함수와는 사용할 수 없고 mysql_store_result() 함수와 사용할 수 있다. offset 인수는 mysql_row_tell() 함수나 mysql_row_seek() 함수를 호출한 리턴값이 되어야 하며, 이 값은 단순한 행 번호를 의미하는 것이 아니다. 만약 행 번호를 이용하여 결과 셋 내에서 행을 찾고자 하는 경우에는 mysql_data_seek() 함수를 사용하여야 한다. 18.4.40.2 Return values 행 커서(row cursor)의 이전값(previous value). 이 값은 mysql_row_seek() 함수의 인수로 넘겨진다. 18.4.40.3 Errors None. 18.4.41 mysql_row_tell() MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *result) 18.4.41.1 Description 마지막 mysql_fetch_row() 함수 호출에 의한 행 커서의 현재 위치를 리턴한다. 이값은 mysql_row_seek() 함수의 인수로 넘겨진다. mysql_row_tell() 함수는 반드시 mysql_store_result() 함수 뒤에 사용되어야 하며, mysql_use_result() 함수 뒤에는 사용할 수 없다. 18.4.41.2 Return values 행 커서의 현재 변위(The current offset of the row cursor). 18.4.41.3 Errors None. 18.4.42 mysql_select_db() int mysql_select_db(MYSQL *mysql, const char *db) 18.4.42.1 Description db 인수에 지정한 데이터베이스를 mysql 인수가 가진 연결에 대한 현재 작업 데이터베이스가 되도록 한다. 이후의 질의에 대해서 여기서 지정한 데이터베이스가 데이터베이스를 명시하지 않은 테이블 참조에 대한 디폴트 데이터베이스로 사용된다. 연결되어 있는 사용자가 db 인수에 지정된 데이터베이스를 사용할 권한을 가지고 있다는 것이 인증되지 않으면 mysql_select_db() 함수는 실패한다. 18.4.42.2 Return values 성공이면 0, 에러이면 0이 아닌 값 18.4.42.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.43 mysql_shutdown() int mysql_shutdown(MYSQL *mysql) 18.4.43.1 Description 데이터베이스 서버로 하여금 셧다운되도록 요청하며, 현재 연결된 사용자가 셧다운 권한을 가지고 있어야 한다. 18.4.43.2 Return values 성공이면 0, 에러이면 0이 아닌 값을 리턴한다. 18.4.43.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.44 mysql_stat() char *mysql_stat(MYSQL *mysql) 18.4.44.1 Description 'mysqladmin status' 명령어에 의해 제공되는 정보와 비슷한 정보를 포함하고 있는 문자열을 리턴한다. 이 문자열에는 구동시간(uptime), 실행되고 있는 쓰레드 수, 질문(question), 재시동(reload), 열려있는 테이블 등에 대한 정보가 포함되어 있다. 18.4.44.2 Return values 서버 상태를 기술하는 문자열. 에러이면 NULL을 리턴한다. 18.4.44.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.45 mysql_store_result() MYSQL_RES *mysql_store_result(MYSQL *mysql) 18.4.45.1 Description 데이터를 얻어오는 질의(SELECT, SHOW, DESCRIBE, EXPLAIN)의 수행에 대하여 mysql_store_result() 혹은 mysql_use_result() 함수를 호출한다. mysql_store_result() 함수는 전체 질의 결과를 클라이언트로 읽어오며, MYSQL_RES 구조체를 할당하고 결과를 이 구조체에 넣어준다. 아무 행도 리턴되지 않으면 빈 결과 셋(empty result set)이 리턴된다(빈 결과 셋은 NULL 리턴 값과는 다르다).
mysql_store_result() 함수를 호출하면 mysql_num_rows() 함수를 호출하여 결과 셋 내에 얼마나 많은 행들이 있는가를 알아 볼 수 있다. mysql_fetch_row() 함수를 호출하여 결과 셋으로부터 행들을 얻어올 수 있으며, 혹은 mysql_row_seek()와 mysql_row_tell() 함수를 통하여 결과 셋 내에서의 현행 위치를 얻거나 위치를 설정해줄 수 있다. 결과셋을 통한 작업이 끝나면 반드시 mysql_free_result() 함수를 호출해준다. 18.4.45.2 Return values 결과가 저장된 MYSQL_RES 결과 구조체(result structure). 에러이면 NULL을 리턴. 18.4.45.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_OUT_OF_MEMORY Out of memory. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred. 18.4.46 mysql_thread_id() unsigned long mysql_thread_id(MYSQL *mysql) 18.4.46.1 Description 현재 연결에 대한 쓰레드 ID를 리턴한다. 이 값은 mysql_kill() 함수의 인수로 사용되어 쓰래드를 kill 하는데 사용될 수 있다. 18.4.46.2 Return values 현재 연결에 대한 쓰레드 ID. 18.4.46.3 Errors None. 18.4.47 mysql_use_result() MYSQL_RES *mysql_use_result(MYSQL *mysql) 18.4.47.1 Description 데이터를 얻어오는 질의(SELECT, SHOW, DESCRIBE, EXPLAIN)의 수행에 대하여 mysql_store_result() 혹은 mysql_use_result() 함수를 호출한다. mysql_use_result() 함수는 결과 셋을 얻어오는 작업을 초기화하지만 mysql_store_result() 함수처럼 실제로 결과 셋을 읽어서 클라이언트에게 넘겨주지는 않는다. 대신 mysql_fetch_row() 함수를 각각 호출함으로써 각 행이 하나씩 얻어진다. 이것은 질의의 결과를 임시 테이블이나 지역 버퍼에 저장하지 않고 서버로부터 직접 읽어오게 되며, 이는 mysql_store_result() 함수에 비하여 좀더 빠르고 훨씬 적은 양의 메모리를 차지한다. 클라이언트는 현재 행에 대한 메모리와 max_allowed_packet 바이트까지 증가할 수 있는 통신 버퍼(communication buffer)만 을 할당하게 된다. 하지만 클라이언트 측에서 각 행별로 많은 작업을 수행하고 있거나 사용자가 ^S(stop scroll)을 입력할 수도 있는 스크린으로 결과를 내보내는 경우에는 mysql_use_result() 함수를 사용해서는 안된다. 이것은 서버를 멈추게 하고 다른 쓰레드들로 하여금 데이터가 얻어지고 있는 테이블을 갱신하는 것을 막게 된다. mysql_use_result() 함수를 사용할 때는 NULL 값이 리턴될 때까지 mysql_fetch_row() 함수를 수행해야 한다. 그렇지 않으면 아직 얻어오지 않은 행들이 다음 질의에 대한 결과 셋으로 넘어가서 리턴되게 된다. C API는 'Commands out of sync' 에러를 주게 된다. mysql_use_result() 함수로부터 리턴되는 결과에 대해서 mysql_data_seek(), mysql_row_seek(), mysql_row_tell(), mysql_num_rows(), mysql_affected_rows()과 같은 함수들을 사용할 수 없으며, 혹은 mysql_use_result() 함수가 종료할 때까지 다른 질의를 수행할 수 없다(그러나 모든 행들을 fetch한 후에는 mysql_num_rows() 함수가 실제로 fetch되어진 행의 개수를 리턴한다). 결과 셋에 대한 작업이 끝나면 반드시 mysql_free_result()를 호출하여야 한다. 18.4.47.2 Return values MYSQL_RES 결과 구조체(result structure). 에러이면 NULL을 리턴한다. 18.4.47.3 Errors CR_COMMANDS_OUT_OF_SYNC Commands were executed in an improper order. CR_OUT_OF_MEMORY Out of memory. CR_SERVER_GONE_ERROR The MySQL server has gone away. CR_SERVER_LOST The connection to the server was lost during the query. CR_UNKNOWN_ERROR An unknown error occurred.
18.4.48 mysql_query() 함수가 성공하였는데 mysql_store_result() 함수가 가끔 NULL을 리턴하는 이유는 무엇인가? 이런 경우가 있을 수 있으며 이것은 다음 중 하나의 상황이 발생하였음을 의미한다: malloc()이 실패한 경우(예를 들어 결과 셋이 너무 큰 경우). 데이터를 읽을 수 없는 경우(연결에 에러가 생기는 등). 질의가 아무 데이터도 리턴하지 않는 경우(INSERT, UPDATE, DELETE 문 등의 경우). 질의문이 비어있지 않은(non-empty) 결과를 생성하였나는 mysql_num_fields() 함수를 호출함으로써 체크해볼 수 있다. 만약 mysql_num_fields() 함수가 0을 리턴하면 결과셋이 빈 것이고 가장 마지막 질의가 INSERT, DELETE와 같이 값을 리턴하지 않는 질의문임을 의미한다. mysql_num_fields() 함수가 0이 아닌 값을 리턴하는 경우는 질의문이 비어있지 않는 결과를 생성해야만 함을 의미한다. 자세한 내용은 mysql_num_fields() 함수의 설명을 참조한다. mysql_errno() 함수나 mysql_error() 함수를 호출함으로써 에러를 테스트해볼 수 있다. 18.4.49 What results can I get from a query? 질의의 결과로 리턴되는 결과 셋에 덧붙여 다음과 같은 정보들을 또한 얻을 수 있다: - mysql_affected_rows()는 INSERT, UPDATE, DELETE 문을 수행할 때 가장 최근에 수행된 질의에 의해 affected된 행들의 개수를 리턴한다. 예외는 DELETE가 WHERE 구문없이 사용되어 테이블이 truncate되는 경우이다. 이 경우 mysql_affected_rows() 함수는 affected된 레코드의 숫자로서 0을 리턴한다. - mysql_num_rows()는 결과 셋 내의 행의 개수를 리턴한다. mysql_store_result() 함수와 함께 사용되는 경우에는 mysql_store_result()가 리턴되자마자 최대한 빨리 mysql_num_rows()가 호출되어진다. mysql_use_result()와 함께 사용되는 경우에는 mysql_fetch_row()가 모든 행에 대해서 수행된 후에만 mysql_num_rows()가 호출될 수 있다. - mysql_insert_id()는 AUTO_INCREMENT 인덱스를 가진 테이블에 행을 추가한 경우 가장 최근에 새로 생성된 ID를 리턴한다. - 몇몇 질의들(LOAD DATA INFILE ..., INSERT INTO ... SELECT ..., UPDATE)은 부가적인 정보를 리턴한다. 이 결과들은 mysql_info()에 의하여 리턴된다. mysql_info()는 리턴할 부가적인 정보가 없는 경우 NULL을 리턴한다. 18.4.50 How can I get the unique ID for the last inserted row? AUTO_INCREMENT 속성을 가지는 컬럼을 포함하고 있는 테이블에 새로운 레코드를 삽입하는 경우, mysql_insert_id() 함수를 호출함으로써 가장 최근에 생성된 ID를 얻어올 수 있다. 다음의 코드를 수행함으로써 AUTO_INCREMENT 인덱스가 사용되었나를 체크해 볼 수 있다. 또한 질의가 AUTO_INCREMENT 인덱스를 가진 INSERT 문인가를 체크할 수 있다: if (mysql_error(&mysql)[0] == 0 && mysql_num_fields(result) == 0 && mysql_insert_id(&mysql) != 0) { used_id = mysql_insert_id(&mysql); } 하나의 테이블에서 생성된 ID를 다른 테이블에 삽입하는데 사용하고자 하는 경우 다음과 같은 SQL 문을 사용한다: INSERT INTO foo (auto, text) VALUES(NULL, 'text'); # generate ID by inserting NULL INSERT INTO foo2 (id, text) VALUES(LAST_INSERT_ID(), 'text'); # use ID in second table 18.4.51 Problems linking with the C API 어떤 시스템에서는 C API를 linking하여 컴파일할 때 다음과 같은 에러가 발생할 수 있다: gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl Undefined first referenced symbol in file floor /usr/local/lib/mysql/libmysqlclient.a(password.o) ld: fatal: Symbol referencing errors. No output written to client 위와 같은 에러가 발생하는 경우에는 컴파일 시에 -lm을 추가함으로써 math 라이브러리를 함께 포함해 준다. 18.4.52 How to make a thread-safe client 클라이언트는 거의 thread-safe하다. 가장 큰 문제점은 'net.c'에서 소켓을 읽는 서브루틴들이 interrupt-safe하지 못하다는 것이다. 이것은 서버로부터 읽는 작업이 오래 걸릴 때 클라이언트가 작업을 중단할 수 있는 기능을 원할 것이라는 생각에서 그렇게 작성되어졌다. 표준 클라이언트 라이브러리는 쓰레드 옵션없이 컴파일되어진다.
Thread-safe 클라이언트를 만들기 위해서는 -lmysys, -lstring, -ldbug 라이브러리와 서버가 사용하는 net_serv.o를 함께 사용한다. Threaded client를 사용하면 'thr_alarm.c' 파일에 있는 루틴들을 활용할 수 있다. mysys 라이브러리의 루틴들을 사용할 때 기억해야할 단 한가지는 my_init() 함수를 가장 먼저 호출해야 한다는 것이다! mysql_real_connect()를 제외한 모든 함수들은 현재 thread-safe하다. 다음의 내용에서는 thread-safe 클라이언트 라이브러리를 컴파일하는 방법과 그것을 thread-safe 방식으로 사용하는 방법에 대하여 기술한다(여기서는 mysql_real_connect() 함수에 대한 예를 설명하며, mysql_connect()의 경우에도 동일하다). mysql_real_connect() 함수를 thread-safe하게 만들기 위해서는 다음의 명령으로 클라이언트를 재컴파일하여야 한다: shell> CPPFLAGS=-DTHREAD_SAFE_CLIENT ./configure ... pthread 라이브러리가 디폴트로 포함되어지지 않기 때문에 표준 클라이언트(standard client)를 링킹할 때 정의되지 않은 심볼(undefined symbols)로 인한 에러가 발생할 수 있다. 결과로 나오는 'libmysqld.a' 라이브러리는 이젠 thread-safe하다. 이것은 두개의 thread가 mysql_real_connect()에 의해 리턴된 동일한 연결 핸들(connection handle)을 동시에 질의하지 않는 한 클라이언트 코드가 thread-safe하다는 것을 의미한다; 클라이언트/서버 프로토콜은 주어진 연결에 대하여 동시에 하나의 요청만을 허용한다. 동일한 연결에 대하여 복수개의 thread를 사용하길 원하는 경우에는 mysql_query()와 mysql_store_result()의 호출 묶음(call combination)에 대하여 mutex lock을 해야 한다. 일단 mysql_store_result()가 준비되면 lock은 해제될 수 있으며 다른 thread들은 동일한 연결에 대하여 query를 할 수 있다(다시 말해서, 서로 다른 thread들이 적절한 locking 프로토콜을 사용하는 한 mysql_store_result()과 함께 생성된 서로 다른 MYSQL_RES 포인터들을 사용할 수 있다). POSIX thread로 프로그램한다면 mutex lock을 생성하고 해제하는데 pthread_mutex_lock()와 pthread_mutex_unlock() 함수를 사용할 수 있다. mysql_store_result()가 아닌 mysql_use_result()를 사용하는 경우에는 lock이 mysql_use_result()와 mysql_fetch_row()에 대한 호출을 surround할 필요가 있다. 그러나 threaded client는 mysql_use_result()를 사용하지 않는 것이 가장 좋다.

Posted by Golmong
: