SQLPutLob
SQLPutLob#
SQLPutLob은 LOB 데이터를 삽입하거나 갱신할 때 사용한다. 이 함수의 모든 동작은 내부적으로 갱신 작업에 해당한다. LOB 데이터를 삽입하는 것은 길이가 0인 LOB 데이터를 다른 값으로 갱신하는 것을 의미하며 LOB 데이터를 갱신하는 것은 기존 LOB 데이터에서 특정 위치의 값을 다른 값으로 변경하거나 LOB 데이터 뒤에 데이터를 추가하는 것을 의미한다. 이 함수를 실행하는 세션은 반드시 자동 커밋 모드를 해제해야 하며, LOB 위치 입력기를 얻는 함수를 먼저 실행해야 한다. 관련 내용은 LOB 데이터 처리 방식에서 확인할 수 있다.
SQLPutLob 함수는 Altibase CLI에서 LOB 데이터를 다루기 위해 제공하는 특수한 함수로, ODBC 표준에는 없다.
구 문#
SQLRETURN SQLPutLob(
SQLHSTMT stmt,
SQLSMALLINT locatorCType,
SQLUBIGINT targetLocator,
SQLUINTEGER fromPosition,
SQLUINTEGER forLength,
SQLSMALLINT sourceCType,
SQLPOINTER value,
SQLUINTEGER valueLength);
인 자#
자료유형 | 인자 | 사용 | 설명 |
---|---|---|---|
SQLHSTMT | stmt | 입력 | 검색된 결과들에 대한 명령문 핸들 |
SQLSMALLINT | locatorCType | 입력 | 삽입 또는 갱신할 LOB 위치 입력기의 C 데이터 타입 식별자. SQL_C_BLOB_LOCATOR 또는 SQL_C_CLOB_LOCATOR가 올 수 있다. |
SQLUBIGINT | targetLocator | 입력 | LOB 위치 입력기. LOB 데이터를 삽입 또는 갱신할 LOB 데이터를 가리킨다. |
SQLUINTEGER | fromPosition | 입력 | LOB 데이터를 삽입 또는 갱신할 시작 위치로, 0부터 시작하며 LOB 데이터를 삽입할 때는 0이어야 한다. 단위는 바이트이다. |
SQLUINTEGER | forLength | 입력 | 사용되지 않음 |
SQLSMALLINT | sourceCType | 입력 | CLI 애플리케이션 버퍼를 나타내는 C 데이터 타입 식별자. 이 버퍼는 삽입 또는 갱신할 LOB 데이터를 담고 있다. BLOB 데이터는 SQL_C_BINARY, CLOB 데이터는 SQL_C_CHAR가 올 수 있다. |
SQLPOINTER | value | 입력 | CLI 애플리케이션 버퍼를 가리키는 포인터 |
SQLUINTEGER | valueLength | 입력 | CLI 애플리케이션 버퍼에 저장된 LOB 데이터의 길이로, 1부터 시작한다. 단위는 바이트이다. SQL_NULL_DATA는 설정할 수 없다. |
결괏값#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
설 명#
이 함수는 CLI 애플리케이션 버퍼 value에 담긴 LOB 데이터를 LOB 위치 입력기 targetLocator가 가리키고 있는 LOB 데이터에 갱신한다. 이때, 갱신되는 위치는 fromPosition 부터 valueLength 까지이다.
LOB 데이터 삽입#
INSERT 문으로 LOB 데이터를 삽입할 때 이 함수를 사용할 수 있다. 이때, fromPosition은 0이어야 한다. 이것은 targetLocator가 길이가 0인 LOB 데이터를 가리키는 것을 의미한다.
LOB 데이터 전체 갱신#
UPDATE 문으로 LOB 타입 칼럼 전체를 갱신할 때 이 함수를 사용할 수 있다. 이 함수의 동작은 LOB 데이터 삽입 방식과 같으며 fromPosition도 0이어야 한다.
LOB 데이터 부분 갱신#
SQLPutLob 함수를 사용하여 기존 LOB 데이터에서 특정 위치의 값을 갱신할 수 있다. 이때, LOB 위치 입력기를 얻기 위해 SELECT lob_column_name FROM table_name WHERE … FOR UPDATE 문장을 먼저 수행해야 한다. 이 함수의 동작 역시 LOB 데이터 삽입 방식과 같으나 fromPosition은 기존 LOB 데이터에서 갱신할 시작 위치를 지정해야 한다. fromPosition에 기존 LOB 데이터의 끝 위치를 지정하면, CLI 애플리케이션 버퍼(value)에 담긴 LOB 데이터가 기존 데이터 뒤에 추가된다.
SQL_ERROR 반환#
targetLocator 인자가 유효하지 않을 때 SQL_ERROR를 반환한다.
fromPosition 인자가 함수 실행 시점의 targetLocator가 가리키는 LOB 타입 칼럼의 길이보다 크면 SQL_ERROR를 반환한다.
진 단#
SQLSTATE | 설명 | 부연설명 |
---|---|---|
08S01 | 통신 회선 장애 (데이터 송수신 실패) | Altibase CLI 드라이버와 DB간에 함수 처리가 완료되기 전에 통신 회선 실패 |
HY000 | 일반 오류 |
관련 함수#
SQLGetLobLength
SQLGetLob
예 제#
아래는 SQLBindCol 함수 예제에서 사용한 테이블 생성 구문이다.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 CLOB);
CLOB 데이터 삽입 후 부분 갱신#
CLOB 칼럼 값이 'Hybrid dbms Altibase'인 레코드를 삽입 후 'dbms'를 'DBMS'로 변경한다.
SQLCHAR buf[20];
SQLINTEGER lobInd;
SQLUBIGINT lobLoc;
strcpy(query, "INSERT INTO T1 VALUES (5, ?)");
if (SQLPrepare(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLPrepare : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/*
SQLExecute 함수에서 LOB 위치 입력기를 얻을 수 있도록 SQLBindParameter 함수에서 LOB 위치 입력기 인자를 바인딩한다.
*/
if (SQLBindParameter(stmt, 1, SQL_PARAM_OUTPUT, SQL_C_CLOB_LOCATOR, SQL_CLOB_LOCATOR, 0, 0, &lobLoc, 0, &lobInd) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLBindParameter : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/*
SQLExecute 함수를 호출한다.
*/
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecute : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* SQLPutLob 함수로 CLOB 데이터를 삽입한다. */
memcpy(buf, "Hybrid dbms Altibase", 20);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 0, 0, SQL_C_CHAR, buf, 20) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLPutLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* SQLPutLob 함수로 CLOB 데이터를 부분 갱신한다. */
/* 'Hybrid dbms Altibase'에서 8번째 위치(fromPosition+1)부터 12번째 위치까지 'DBMS'로 치환 */
memcpy(buf, "DBMS", 4);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 7, 0, SQL_C_CHAR, buf, 4) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLPutLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLFreeLob(stmt, lobLoc) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLFreeLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
CLOB 데이터 전체 갱신#
여러 레코드의 CLOB 칼럼을 일괄적으로 'Retail'로 변경한다.
SQLCHAR buf[6];
SQLINTEGER lobInd;
SQLUBIGINT lobLoc;
strcpy(query, "UPDATE T1 SET i2=? WHERE i1>=1 AND i1<=100");
if (SQLPrepare(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLPrepare : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/*
SQLExecute 함수에서 LOB 위치 입력기를 얻을 수 있도록 SQLBindParameter 함수에서 LOB 위치 입력기 인자를 바인딩한다.
*/
if (SQLBindParameter(stmt, 1, SQL_PARAM_OUTPUT, SQL_C_CLOB_LOCATOR, SQL_CLOB_LOCATOR, 0, 0, &lobLoc, 0, &lobInd) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLBindParameter : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/*
SQLExecute 함수를 호출한다.
*/
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecute : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* SQLPutLob 함수로 CLOB 데이터를 전체 갱신한다. */
memcpy(buf, "Retail", 6);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 0, 0, SQL_C_CHAR, buf, 6) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLPutLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLFreeLob(stmt, lobLoc) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLFreeLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
CLOB 데이터 부분 갱신#
CLOB 칼럼 값이 'Ver.Beta'인 레코드 삽입 후 'Beta' 부분을 'Gamma'로 치환
SQLCHAR buf[5];
SQLUBIGINT lobLoc;
.
/* CLOB 타입 칼럼에 "Ver.Beta"를 삽입 */
strcpy(query, "INSERT INTO T1 VALUES (1, 'Ver.Beta')");
if (SQLExecDirect(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecDirect : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* 아래부터는 SQLPutLob 함수로 CLOB 데이터를 부분 갱신하는 예제이다. */
/* LOB 위치 입력기를 얻기 위해 SELECT FOR UPDATE 문을 먼저 수행한다. */
strcpy(query, "SELECT i2 FROM T1 WHERE i1=1 FOR UPDATE");
if (SQLExecDirect(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecDirect : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* SQLFetch 함수에서 LOB 위치 입력기를 얻을 수 있도록 SQLBindCol 함수에서 LOB 위치 입력기 인자를 바인딩한다. */
if (SQLBindCol(stmt, 1, SQL_C_CLOB_LOCATOR, &lobLoc, 0, NULL) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLBindCol : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLFetch(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLFetch : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* SQLPutLob 함수로 기존 LOB 데이터의 마지막 부분을 다른 데이터로 변경한다. */
/* 'Ver.Beta'에서 Beta 부분을 Gamma로 변경 */
memcpy(buf, "Gamma", 5);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 4, 0, SQL_C_CHAR, buf, 5) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLPutLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLFreeLob(stmt, lobLoc) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLFreeLob : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}