프리페어드 명령문은 여러 가지의 데이터 구조를 사용한다:
- 명령문을 미리 준비하기 위해서는, 명령문 스트링을 mysql_stmt_init() 함수에 전달하는데, 이 함수는 MYSQL_STMT 데이터 구조에 대한 포인터를 리턴한다.
- 프리페어드 명령문에 대한 파라미터를 제공하기 위해서는, MYSQL_BIND 구조를 설정하고 그것을 mysql_stmt_bind_param()에 전달한다. 결과 컬럼 값을 받기 위해서는, MYSQL_BIND 구조를 설정하고 그것을 mysql_stmt_bind_result()에 전달한다.
- MYSQL_TIME 구조는 임시 데이터를 양 방향으로 전송하기 위해 사용한다.
아래에서는 프리페어드 명령문 데이터 타입을 보다 자세하게 설명하고 있다.
이 구조는 프리페어드 명령문을 나타낸다. 하나의 명령문은 mysql_stmt_init()를 호출해서 생성하는데, 이 함수는 명령문 핸들을 리턴한다 (즉, MYSQL_STMT에 대한 포인터). 핸들은 mysql_stmt_close()를 사용해서 명령문을 닫기 전까지 명령문과 관련된 모든 연산용으로 사용된다.
MYSQL_STMT 구조에는 어플리케이션이 사용할 수 있는 멤버가 들어 있지 않다. 또한, MYSQL_STMT 구조를 복사하고자 시도하지 말도록 한다. 이렇게 복사한 것이 올바르게 동작할 것이라고는 보장할 수 없다.
이 구조는 명령문 입력 (서버에 전달되는 데이터 값)용 및 출력 (서버가 리턴하는 결과 값)용으로 모두 사용할 수 있다:
- 입력의 경우, MYSQL_BIND는 mysql_stmt_execute()가 사용할 수 있도록 파라미터 데이터 값을 버퍼에 넣기 위해서 mysql_stmt_bind_param()와 함께 사용된다.
- 출력의 경우, MYSQL_BIND는 mysql_stmt_fetch()와 함께 열을 패칭할 때 사용하기 위해서 결과 셋 버퍼를 mysql_stmt_bind_result()와 함께 사용한다.
MYSQL_BIND 구조를 사용하기 위해서는 0으로 초기화 시킨 후에 적당한 멤버로 설정해야 한다. 예를 들면, 세 개의 MYSQL_BIND 구조 어레이를 선언하고 초기화 시키기 위해서는 다음과 같은 코드를 사용한다:
MYSQL_BIND bind[3];
memset(bind, 0, sizeof(bind));
MYSQL_BIND 구조는 어플리케이션 프로그램이 사용할 수 있는 용도로 다음과 같은 멤버를 가지고 있다. 몇몇 멤버의 경우, 각 사용 방법이 그 구조가 입력용인지 또는 출력용인지에 따라서 결정된다.
- enum enum_field_types buffer_type
버퍼 타입. 이 멤버는 명령문 파라미터에 바인딩한 C 언어 변수의 데이터 타입을 나타낸다. 사용 가능한 buffer_type 값은 이 섹션 후반부에 나와 있다. 입력용의 경우, buffer_type은 서버에 전달할 값을 가지고 있는 변수 타입을 가리킨다. 출력용의 경우에는 서버에서 전달 받고자 하는 값의 변수 타입을 나타낸다.
- void *buffer
데이터 전송용으로 사용하는 버퍼를 가리키는 포인다. 이것은 변수의 주소가 된다.
입력의 경우, buffer는 명령문 파라미터 데이터 값이 저장되어 있는 변수를 가리키는 포인터이다. mysql_stmt_execute()를 호출하면, MySQL은 변수에 저장되어 있는 값을 가져와서 명령문에 있는 해당 파라미터 마커에 넣는다.
출력의 경우, buffer는 결과 셋 컬럼 값을 리턴하는 변수를 가리키는 포인터이다. mysql_stmt_fetch()를 호출하면, MySQL은 컬럼 값을 리턴하고 그것을 이 변수에 저장한다.
- unsigned long buffer_length
*buffer의 실제 크기 (바이트). 이것은 버퍼에 저장할 수 있는 최대 데이터 크기를 나타낸다. 문자 및 바이너리 C 데이터의 경우, buffer_length 값은 입력 값을 지정하기 위해서 mysql_stmt_bind_param()를 사용할 때의 *buffer 크기를 나타거나, 또는 mysql_stmt_bind_result()를 사용할 때 버퍼에 가져올 수 있는 출력 데이터 바이트의 최대 크기를 나타낸다.
- unsigned long *length
*buffer에 저장된 데이터의 실제 바이트 크기를 나타내는 unsigned long 변수를 가리키는 포인터. length는 문자 또는 바이너리 C 데이터용으로 사용된다.
입력 파라미터 데이터 바인딩의 경우, length는 *buffer에 저장되어 있는 파라미터 값의 실제 길이를 나타내는 변수 unsigned long를 가리킨다; 이것은 mysql_stmt_execute()가 사용한다.
출력 값 바인딩의 경우, mysql_stmt_fetch()의 리턴 값은 길이를 해석할 때 사용한다:
- mysql_stmt_fetch()가 0을 리턴한다면, *length는 파라미터 값의 실제 길이를 나타낸다.
- mysql_stmt_fetch()가 MYSQL_DATA_TRUNCATED를 리턴한다면, *length는 절사되지 않은 파라미터 값의 크기를 나타낸다. 이와 같은 경우, *length 및 buffer_length의 최소 길이는 값의 실제 길이를 나타낸다.
데이터 값의 길이는 buffer_type 값으로 판단하기 때문에 length에서 숫자와 임시 데이터 타입은 무시된다.
- my_bool *is_null
이 멤버는 my_bool 변수를 가리키며, 그 값이 NULL이면 참 (true), NULL이 아니면 거짓 (false)를 나타낸다. 입력의 경우, 명령문 파라미터로 NULL 값을 전달하는 것을 나타내기 위해서는 *is_null을 설정한다.
is_null이 논리 스칼라가 아니라 논리 스칼라에 대한 포인터인 이유는 NULL 값을 지정할 때 유연성을 제공하기 위함이다:
- 데이터 값이 항상 NULL이면, 컬럼을 바인딩할 때 buffer_type 값으로 MYSQL_TYPE_NULL을 사용하도록 한다. 다른 멤버들은 중요하지 않다.
- 데이터 값이 항상 NOT NULL이라면, 바인딩하는 변수용으로는 다른 멤버를 적당히 설정한 후에 is_null = (my_bool*) 0을 설정한다.
- 이외의 모든 다른 경우에는, 다른 멤버를 적당히 설정한 후에 is_null을 my_bool 변수 주소에 설정한다.
출력의 경우, 명령문이 리턴하는 결과 셋 컬럼 값이 NULL일 경우에는 열을 패치한 후에 is_null이 가리키는 값을 참으로 설정한다.
- my_bool is_unsigned
이 멤버는 unsigned (char, short int, int, long long int)가 될 수 있는 데이터 타입과 함께 C 변수용으로 사용된다. buffer가 가리키는 변수가 unsigned이면 is_unsigned를 참 (true)으로 설정하고, 그렇지 않다면 거짓으로 설정한다. 예를 들면, signed char 변수를 buffer와 바인딩한다면, MYSQL_TYPE_TINY의 타입 코드를 지정하고 is_unsigned를 거짓으로 설정한다. unsigned char를 대신 바인딩한다면, 타입 코드는 동일하지만 is_unsigned는 참 (true)가 되어야 한다. (char의 경우에는 부호가 있는지 또는 없는지 결정되지 않기 때문에, signed char 또는 unsigned char를 사용해서 명확하게 부호를 설정하는 것이 좋다.)
is_unsigned는 클라이언트에 있는 C 언어 변수에만 적용된다. 이것은 서버에 있는 SQL 값의 부호에 대해서는 어떠한 영향도 주지 않는다. 예를 들면, BIGINT UNSIGNED 컬럼용 값을 주기 위해서 int 변수를 사용한다면, int가 부호화 타입이기 때문에 is_unsigned는 반드시 거짓이 되어야 한다. BIGINT 컬럼용 값을 주기 위해서 unsigned int 변수를 사용한다면, unsigned int가 부호가 없는 타입이기 때문에 is_unsigned는 반드시 참이 되어야 한다.
- my_bool *error
출력의 경우, 이 멤버가 my_bool 변수를 가리키도록 설정한다. 절사 (truncation) 레포팅을 활성화 한다면, mysql_stmt_fetch()는 MYSQL_DATA_TRUNCATED를 리턴하고 *error는 절사가 발생한 파라미터에 대한 MYSQL_BIND 구조에서 참이 된다. 절사는 부호 표시 부분이 없어졌다는 것을 나타내거나, 또는 스트링이 너무 길어서 컬럼에 들어가지 못한다는 것을 의미하는 것이다.
이 구조는 서버로부터/서버 쪽으로 DATE, TIME, DATETIME, 그리고 TIMESTAMP 데이터를 직접 전달 받고/전달할 때 사용한다. MYSQL_BIND 구조의 buffer_type 멤버를 임시 타입 중의 하나 (MYSQL_TYPE_TIME, MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIMESTAMP)로 설정하고, buffer 멤버가 MYSQL_TIME 구조를 가리키도록 설정한다.
MYSQL_TIME 구조는 아래 테이블에 나와 있는 멤버들을 가지고 있다.
|
Member |
Description |
|
unsigned int year |
The year |
|
unsigned int month |
The month of the year |
|
unsigned int day |
The day of the month |
|
unsigned int hour |
The hour of the day |
|
unsigned int minute |
The minute of the hour |
|
unsigned int second |
The second of the minute |
|
my_bool neg |
A boolean flag to indicate whether the time is negative |
|
unsigned long second_part |
The fractional part of the second in microseconds; currently unused |
아래의 테이블은 입력값용으로 MYSQL_BIND 구조의 buffer_type 멤버에 지정할 수 있는 값을 나타내는 것이다. 값을 선택할 때에는 바인딩하는 C 언어 변수의 데이터 타입을 따르도록 한다. 변수가 unsigned이면, is_unsigned 멤버는 참 (true)으로 설정하도록 한다.
|
Input Variable C Type |
buffer_type Value |
SQL Type of Destination Value |
|
signed char |
MYSQL_TYPE_TINY |
TINYINT |
|
short int |
MYSQL_TYPE_SHORT |
SMALLINT |
|
Int |
MYSQL_TYPE_LONG |
INT |
|
long long int |
MYSQL_TYPE_LONGLONG |
BIGINT |
|
Float |
MYSQL_TYPE_FLOAT |
FLOAT |
|
Double |
MYSQL_TYPE_DOUBLE |
DOUBLE |
|
MYSQL_TIME |
MYSQL_TYPE_TIME |
TIME |
|
MYSQL_TIME |
MYSQL_TYPE_DATE |
DATE |
|
MYSQL_TIME |
MYSQL_TYPE_DATETIME |
DATETIME |
|
MYSQL_TIME |
MYSQL_TYPE_TIMESTAMP |
TIMESTAMP |
|
char[] |
MYSQL_TYPE_STRING (for non-binary data) |
TEXT, CHAR, VARCHAR |
|
char[] |
MYSQL_TYPE_BLOB (for binary data) |
BLOB, BINARY, VARBINARY |
|
|
MYSQL_TYPE_NULL |
NULL |
아래의 테이블은 출력용으로 MYSQL_BIND 구조의 buffer_type 멤버에 지정할 수 있는 값을 나타내는 것이다. 값을 선택할 때에는 바인딩하는 C 언어 변수의 데이터 타입을 따르도록 한다. 변수가 unsigned이면, is_unsigned 멤버도 참 (true)으로 설정하도록 한다.
|
SQL Type of Received Value |
buffer_type Value |
Output Variable C Type |
|
TINYINT |
MYSQL_TYPE_TINY |
signed char |
|
SMALLINT |
MYSQL_TYPE_SHORT |
short int |
|
MEDIUMINT |
MYSQL_TYPE_INT24 |
int |
|
INT |
MYSQL_TYPE_LONG |
int |
|
BIGINT |
MYSQL_TYPE_LONGLONG |
long long int |
|
FLOAT |
MYSQL_TYPE_FLOAT |
float |
|
DOUBLE |
MYSQL_TYPE_DOUBLE |
double |
|
DECIMAL |
MYSQL_TYPE_NEWDECIMAL |
char[] |
|
YEAR |
MYSQL_TYPE_SHORT |
short int |
|
TIME |
MYSQL_TYPE_TIME |
MYSQL_TIME |
|
DATE |
MYSQL_TYPE_DATE |
MYSQL_TIME |
|
DATETIME |
MYSQL_TYPE_DATETIME |
MYSQL_TIME |
|
TIMESTAMP |
MYSQL_TYPE_TIMESTAMP |
MYSQL_TIME |
|
CHAR, BINARY |
MYSQL_TYPE_STRING |
char[] |
|
VARCHAR, VARBINARY |
MYSQL_TYPE_VAR_STRING |
char[] |
|
TINYBLOB, TINYTEXT |
MYSQL_TYPE_TINY_BLOB |
char[] |
|
BLOB, TEXT |
MYSQL_TYPE_BLOB |
char[] |
|
MEDIUMBLOB, MEDIUMTEXT |
MYSQL_TYPE_MEDIUM_BLOB |
char[] |
|
LONGBLOB, LONGTEXT |
MYSQL_TYPE_LONG_BLOB |
char[] |
|
BIT |
MYSQL_TYPE_BIT |
char[] |