SQLBindParameter
SQLBindParameter#
SQL 문의 매개변수 마커를 애플리케이션 변수에 바인드시킨다. SQLExecute()가 호출될 때 자료가 애플리케이션에서 데이터베이스 관리 시스템으로 전송된다.
구 문#
SQLRETURN SQLBindParameter (
SQLHSTMT stmt,
SQLSMALLINT par,
SQLSMALLINT pType,
SQLSMALLINT cType,
SQLSMALLINT sqlType,
SQLULEN columnSize,
SQLSMALLINT scale,
SQLPOINTER value,
SQLLEN valueMax,
SQLLEN * valueLength );
인 자#
자료유형 | 인자 | 사용 | 설명 |
---|---|---|---|
SQLHSTMT | stmt | 입력 | 명령문 핸들 |
SQLSMALLINT | par | 입력 | 매개변수의 순서, 1부터 시작 |
SQLSMALLINT | pType | 입력 | 매개변수 type SQL 문 내의 모든 매개변수들은 입력 변수들이고 (SQL_PARAM_INPUT), 프로시져 호출 시 매개변수들은 입력, 출력, 또는 입/출력 변수들이다. (SQL_PARAM_INPUT, SQL_PARAM_OUTPUT, SQL_PARAM_INPUT_OUTPUT) |
SQLSMALLINT | cType | 입력 | 매개변수의 C 데이터 타입 SQL_C_CHAR SQL_C_SBIGINT 등 <부록 참조> |
SQLSMALLINT | sqlType | 입력 | 매개변수의 SQL 데이터 타입 SQL_CHAR SQL_VARCHAR 등 <부록 참조> |
SQLULEN | columnSize | 입력 | 해당 매개변수 마커의 정밀도를 나타내는 인자로 SQL 타입에 따라서 다음과 같이 사용된다. * SQL_CHAR, SQL_VARCHAR: 매개변수 마커가 사용할 수 있는 최대 길이를 나타낸다. (columnSize가 0인 경우 디폴트 columnSize로 해석되며, SQL_CHAR, SQL_VARCHAR인 경우 32,000으로 columnSize가 할당된다.) * SQL_DECIMAL, SQL_NUMERIC: 매개변수 마커의 십진 유효 숫자 크기를 나타낸다. (columnSize가 0인 경우 디폴트 columnSzie로 해석되며, SQL_DECIMAL, SQL_NUMERIC 두가지 모두 최대 유효숫자 크기인 38로 columnSize가 할당된다.) * SQL_BINARY, SQL_BYTES, SQL_NIBBLE, SQL_VARBIT: 매개변수 마커가 사용할 수 있는 최대 길이를 나타낸다. (columnSize가 0인 경우 디폴트 columnSize로 해석되며, 각 타입에 따른 디폴트 columnSize는 다음과 같다. SQL_BINARY, SQL_BYTE, SQL_VARBIT 인 경우 32000, SQL_NIBBLE 은 254). * 그 외의 타입에서는 사용자가 지정한 columnSize 인자가 무시되고, 다음과 같이 고정된 값이 사용된다. SQL_SMALLINT 5 SQL_INTEGER 10 SQL_BIGINT 19 SQL_REAL 7 SQL_FLOAT 38 SQL_DOUBLE 15 SQL_TYPE_DATE 30 SQL_TYPE_TIME 30 SQL_TYPE_TIMESTAMP 30 SQL_INTERVAL 10 SQL_GEOMETRY 3200 |
SQLSMALLINT | scale | 입력 | *value 또는 매개변수 마커에 따른 십진 숫자 SQL 데이터 타입이 SQL_NUMERIC일 경우 소수점 아래의 자리수 |
SQLPOINTER | value | 입력 (유예중) | SQLExecute() 또는 SQLExecDirect()가 호출되었을 때 매개변수에 대한 실제 데이터의 포인터 |
SQLLEN | valueMax | 입/출력 | 문자 또는 이진 C 데이터에 대한 *value 버퍼의 최대길이 |
SQLLEN * | valueLength | 입력 (유예중) | SQLExecute() 또는 SQLExecDirect()가 호출되었을 때 입력/출력된 데이터 길이의 포인터 |
결괏값#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
설명#
Array Binding
하나의 문장에 매개변수를 배열로 전달하여 네트워크 round-trip 횟수를 줄여서 속도의 향상을 얻을 수 있는 방법이다.
[그림 2-1]은 Array binding을 간략하게 도식화한 것이다. 네트워크 호출 횟수가 줄어들어 짧은 시간에 더 많은 데이터를 전송할 수 있다.
[그림 2‑1] Array Binding 도식화
Array binding에는 아래의 두 종류가 있다.
열 양식 매개변수 바인딩 (Column-wise parameter binding)#
열 양식 바인딩을 사용하기 위해 애플리케이션은 함수 SQLSetStmtAttr()의 인자 Attribute에 SQL_ATTR_PARAM_BIND_TYPE을 설정하고 인자 param에 SQL_PARAM_BIND_BY_COLUMN을 설정한다. 바인드될 각 열에 대해 애플리케이션은 다음 단계를 수행한다.
-
매개변수 버퍼 배열을 할당한다.
-
지시자 버퍼 배열을 할당한다.
-
인자들과 함께 SQLBindParameter()를 호출한다.
-
cType은 매개변수 버퍼 배열내에 단일 원소의 C 데이터 타입이다.
-
sqlType은 매개변수의 SQL 데이터 타입이다.
-
value는 매개변수 버퍼 배열의 주소이다.
-
valueMax는 매개변수 버퍼 배열내에 단일 원소의 크기이다.
-
valueLength는 길이/지시자 배열의 주소이다.
다음 그림은 각 열에 대해 어떻게 열 양식 바인딩이 작동하는가를 보여준다.
[그림 2‑2] 열 양식 바인딩
예제#
#define DESC_LEN 51
#define ARRAY_SIZE 10
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description, Price) "
"VALUES (?, ?, ?)";
SQLUINTEGER PartIDArray[ARRAY_SIZE];
SQLCHAR DescArray[ARRAY_SIZE][DESC_LEN];
SQLREAL PriceArray[ARRAY_SIZE];
SQLINTEGER PartIDIndArray[ARRAY_SIZE], DescLenOrIndArray[ARRAY_SIZE],
PriceIndArray[ARRAY_SIZE];
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLUINTEGER ParamsProcessed;
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use
// column-wise binding.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
// Specify the number of elements in each parameter array.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
// Specify an array in which to return the status of each set of
// parameters.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
// Specify an SQLUINTEGER value in which to return the number of sets of
// parameters processed.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
// Bind the parameters in column-wise fashion.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
PartIDArray, 0, PartIDIndArray);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
DescArray, DESC_LEN, DescLenOrIndArray);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
PriceArray, 0, PriceIndArray);
행 양식 매개변수 바인딩 (Row-wise parameter binding)#
행 양식 바인딩을 사용할 때, 애플리케이션은 바인드될 각 매개변수에 대해 매개변수와 길이/지시자 버퍼를 포함한 구조(배열)를 정의한다.
행 양식 바인딩을 사용하기 위해 애플리케이션은 다음 단계를 수행한다.
매개변수들(매개변수와 길이/지시자 버퍼를 포함)의 단일 집합을 보유하기위한 구조(배열)를 정의한다.
행 양식 바인딩을 사용하기 위해 애플리케이션은 함수 SQLSetStmtAttr()의 인자 Attribute에 SQL_ATTR_PARAM_BIND_TYPE을 설정하고 인자 param에 프로그램 변수들을 (매개변수들의 단일 집합) 보유하고 있는 구조(배열)의 크기를 설정하고 배열의 첫 원소에 각 구성요소(member)의 주소를 바인드한다.
다음 인자들과 함께 SQLBindParameter()를 호출한다.
-
cType은 매개변수 버퍼 구성요소의 타입이다.
-
sqlType은 매개변수의 SQL 데이터 타입이다.
-
value는 첫 배열 원소(element)에 매개변수 버퍼 구성요소의 주소이다.
-
valueMax는 매개변수 버퍼 구성요소의 크기이다.
-
valueLength는 바운드될 길이/지시자 구성요소의 주소이다.
다음 그림은 행 양식 바인딩이 작동하는 방법을 보여준다.
[그림 2‑3] 행 양식 바인딩
예제#
#define DESC_LEN 51
#define ARRAY_SIZE 10
typedef tagPartStruct {
SQLREAL Price;
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLINTEGER PriceInd;
SQLINTEGER PartIDInd;
SQLINTEGER DescLenOrInd;
} PartStruct;
PartStruct PartArray[ARRAY_SIZE];
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description,
Price) "
"VALUES (?, ?, ?)";
SQLUSMALLINT i, ParamStatusArray[ARRAY_SIZE];
SQLUINTEGER ParamsProcessed;
// Set the SQL_ATTR_PARAM_BIND_TYPE statement attribute to use
// column-wise binding.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, sizeof(PartStruct), 0);
// Specify the number of elements in each parameter array.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, ARRAY_SIZE, 0);
// Specify an array in which to return the status of each set of
// parameters.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, ParamStatusArray, 0);
// Specify an SQLUINTEGER value in which to return the number of sets of
// parameters processed.
SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &ParamsProcessed, 0);
// Bind the parameters in row-wise fashion.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&PartArray[0].PartID, 0, &PartArray[0].PartIDInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
PartArray[0].Desc, DESC_LEN, &PartArray[0].DescLenOrInd);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&PartArray[0].Price, 0, &PartArray[0].PriceInd);
제약사항#
SQL_BINARY, SQL_BYTES, SQL_NIBBLE, SQL_VARBIT 타입은 buffer size나 column size를 반드시 기술해야 한다.
SQL_CHAR, SQL_VARCHAR 타입의 경우 디폴트 precision은 칼럼이 가질 수 있는 최대 크기이며 SQL_NUMERIC, SQL_NUMBER 타입의 경우에는 precision 값으로 38을 갖는다.
주의 사항#
value 인자에 empty string('')에 대한 포인터로 설정하고, cType 인자에 SQL_C_CHAR로 설정한 상태에서, sqlType 인자를 native타입(SQL_DOUBLE, SQL_REAL, SQL_BIGINT, SQL_INTEGER, SQL_SMALLINT)으로 하면 0으로 입력이 되고, non-native타입(SQL_NUMERIC, SQL_DECIMAL, SQL_FLOAT)으로 하면 NULL로 입력된다.
진 단#
SQLSTATE | 설명 | 부연설명 |
---|---|---|
07006 | 제한된 데이터 타입 속성 위반 | cType 데이터 타입은 sqlType 데이터 타입으로 변환될 수 없다. |
07009 | 유효하지 않은 번호 | 명시된 par의 값이 1 보다 작음 |
HY000 | 일반 오류 | |
HY001 | 메모리 할당 오류 | 명시된 핸들에 대한 메모리 할당 실패 |
HY003 | Application buffer type이 유효하지 않음 | cType의 값이 유효한 C 데이터 타입이 아님 |
HY009 | 유효하지 않은 인자 사용 (null pointer) | value가 null pointer, valueLength가 null pointer 그리고 pType이 SQL_PARAM_OUTPUT이 아님. |
HY090 | 유효하지 않은 버퍼 길이 | valueMax 값이 0 보다 작거나 64K 보다 큼 |
HY105 | 유효하지 않은 매개변수 타입 | pType이 유효한 값이 아님 (in, out, inout) |
관련 함수#
SQLExecDirect
SQLExecute
SQLFreeStmt
예 제#
< $ALTIBASE_HOME/sample/SQLCLI/demo_ex2.cpp 참고 >
sprintf(query,"INSERT INTO DEMO_EX2 VALUES( ?, ?, ?, ?, ?, ? )");
/* prepares an SQL string for execution */
if (SQLPrepare(stmt, (SQLCHAR *)query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* binds a buffer to a parameter marker in an SQL statement */
if (SQLBindParameter(stmt,
1, /* Parameter number, starting at 1 */
SQL_PARAM_INPUT, /* in, out, inout */
SQL_C_CHAR, /* C data type of the parameter */
SQL_CHAR, /* SQL data type of the parameter : char(8)*/
8, /* size of the column or expression, precision */
0, /* The decimal digits, scale */
id, /* A pointer to a buffer for the parameter's data */
sizeof(id), /* Length of the ParameterValuePtr buffer in bytes */
&id_ind /* indicator */
) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindParameter(stmt, 2, SQL_PARAM_INPUT,
SQL_C_CHAR, SQL_VARCHAR,
20, /* varchar(20) */
0,
name, sizeof(name), &name_ind) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindParameter(stmt, 3, SQL_PARAM_INPUT,
SQL_C_SLONG, SQL_INTEGER,
0, 0, &age,
0,/* For all fixed size C data type, this argument is ignored */
NULL) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindParameter(stmt, 4, SQL_PARAM_INPUT,
SQL_C_TYPE_TIMESTAMP, SQL_DATE,
0, 0, &birth, 0, NULL) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindParameter(stmt, 5, SQL_PARAM_INPUT,
SQL_C_SSHORT, SQL_SMALLINT,
0, 0, &sex, 0, NULL) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindParameter(stmt, 6, SQL_PARAM_INPUT,
SQL_C_DOUBLE, SQL_NUMERIC,
10, 3, &etc, 0, &etc_ind) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* executes a prepared statement */
sprintf(id, "10000000");
sprintf(name, "name1");
age = 28;
birth.year=1980;birth.month=10;birth.day=10;
birth.hour=8;birth.minute=50;birth.second=10;
birth.fraction=0;
sex = 1;
etc = 10.2;
id_ind = SQL_NTS; /* id => null terminated string */
name_ind = 5; /* name => length=5 */
etc_ind = 0;
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, query);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}