3. LOB Interface#
This chapter describes functions and data types that can be used for handling LOB data.
LOB data types#
The following table shows SQL data type identifiers that support LOB:
| SQL Type Identifier | Data Type | Description |
|---|---|---|
| SQL_BLOB | BLOB | BLOB is a binary data type with a variable length. |
| SQL_CLOB | CLOB | CLOB is a character data type with a variable length. |
[Table 3‑1] Identifier of the SQL data type
The following table shows C data type identifiers that support LOB. It lists C data type of ODBC for each identifier and their definition.
| C Type Identifier | ODBC C Type | C Type Definition |
|---|---|---|
| SQL_C_BLOB_LOCATOR | SQLUBIGINT | unsigned _int64 |
| SQL_C_CLOB_LOCATOR | SQLUBIGINT | unsigned _int64 |
[Table 3‑2] Identifier for LOB-supported C data types
The name of a 64-bit integer type may vary depending on platform. The _int64 shown in the above table is the name of a 64-bit integer that is used in several platforms.
Use SQL_C_CHAR for CLOB data and SQL_C_BINARY for BLOB data to bind user variables.
To obtain a LOB locator, bind SQL_C_CLOB_LOCATOR or SQL_C_BLOB_LOCATOR appropriately based on the LOB column type. A LOB locator in this context, – a LOB location input scheme – is a handle that is used during LOB data operation like a file pointer in an operating system.
The LOB location input scheme for Read can be obtained after SELECT LOB column name FROM table where… and select are executed. The LOB location input scheme for Write can be obtained after SELECT LOB column name FROM table where… FOR UPDATE are executed.
Since a LOB location input scheme refers to LOB data at a certain point in relation to MVCC, it has the same life cycle with the transaction that has created itself. Therefore, to perform LOB operation with a LOB location input scheme, a connection should be always established in Non-Autocommit Mode.
Care must be taken as there is no LOB type of a user variable such as SQL_C_BLOB or SQL_C_CLOB.
LOB Function Overview#
The functions that are available for manipulating LOB data are as follows:
-
SQLBindFileToCol() (Non-standard)
Full Retrieve -
SQLBindFileToParam() (Non-standard)
Full Insert, Full Update -
SQLGetLobLength() (Non-standard)
Get the length of LOB data. -
SQLGetLob() (Non-standard)
Partial Retrieve -
SQLPutLob() (Non-standard)
Partial Insert, Partial Update, Partial Delete -
SQLFreeLob() (Non-standard)
Release the LOB locator being used. -
SQLGetData(), SQLPutData() (Non-standard)
Full Retrieve/Update -
Other ODBC standard functions
Among the above functions, the functions #1 through #6 are special functions that are provided by Altibase for LOB manipulation, and they are not ODBC standard functions.
ODBC standard functions such as #7 and #8 can be used to access LOB data whether the database column type is LOB or not. However, when only a standard function is used, the functions for partial update and partial retrieve are not available. If a user wants to do programming with ODBC Driver Manager, he should add the following entry to the odbc.ini file:
LongDataCompat = yes
or
LongDataCompat = on
If the above entry is added, the types such as SQL_BLOB and SQL_CLOB are converted to SQL_LONGVARBINARY and SQL_LONGVARCHAR types respectively before they are passed to the user. Therefore, if ODBC Driver Manager is used, transparent manipulation of LOB data can be ensured.
SQLBindFileToCol#
SQLBindFileToCol binds a file or files to the columns in the result set for BLOB or CLOB data type
Syntax#
SQLRETURN SQLBindFileToCol(
SQLHSTMT stmt,
SQLSMALLINT col,
SQLCHAR * fileName,
SQLLEN * fileNameLength,
SQLUINTEGER * fileOptions,
SQLLEN fileNameBufferSize,
SQLLEN * valueLength);
Arguments#
| Data Type | Argument | In/Output | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | An instruction handle for the found results. |
| SQLSMALLINT | col | Input | Begins from #1 in the order of columns in the result set to bind. |
| SQLCHAR * | filename | Input (Pending) | A pointer to the buffer that holds a filename or an array of filenames. It cannot be NULL.Upon SQLFetch(), there should be a filename stored in this buffer, and SQLFetch() returns data to the file(s).Either of an absolute path (recommended) and a relative path is allowed. |
| SQLLEN * | fileNameLength | Input (Pending) | A pointer to the buffer that holds a filename length or an array of filename lengths.Upon SQLFetch(), there should be a filename length stored in this buffer.If this argument is NULL, a filename is regarded as a null-terminated string. That is, it has the same effect as if SQL_NTS were stored in the memory pointed by this argument.The max. length of a filename is 255 characters. |
| SQLUINTEGER * | fileOptions | Input (Pending) | A pointer to the buffer that holds a file option or an array of file options. Upon SQLFetch(), there should a file option stored in this buffer. The following options are available: SQL_FILE_CREATE creates one if there is no file, and returns SQL_ERROR if there is a file. SQL_FILE_OVERWRITE creates one if there is no file, and overwrites it if there is a file. SQL_FILE_APPEND creates one if there is no file, and appends to it if there is a file.Only one of the above options can be selected and there is no default option. This argument cannot be NULL. |
| SQLLEN | fileNameBufferSize | Input | Sets the length of the fileName buffer. |
| SQLLEN * | valueLength | Output(Pending) | A pointer to the buffer that holds an indicator variable or an array of indicator variables. It cannot be NULL. It is used to return the length of the data stored in a file or to indicate that LOB is NULL. SQLFetch() can return the following values to the buffer pointed by this pointer: 1. Data length, 2. SQL_NULL_DATA. |
Return Values#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
Description#
SQLBindFileToCol() binds LOB data in the result set to a file, and SQLBindCol() binds it to an application variable (memory buffer).
If SQLFetch() is called after SQLBindFileToCol() is called, LOB data from DBMS is stored in a file, and the length (byte) of the data stored in the file is stored in the buffer pointed by the valueLength pointer. If LOB is NULL, SQL_NULL_DATA is stored in the buffer pointed by the valueLength pointer. The values of fileName, fileNameLength and fileOptions arguments are referred to upon SQLFetch(), and any error in these arguments is also reported during fetching.
To transfer more than one LOB to a file at once upon fetching, all of the fileName, fileNameLength, fileOptions and valueLength arguments should be arrays.
Diagnosis#
| SQLSTATE | Description | Comments |
|---|---|---|
| 08S01 | Communication line fault (Data transmission failure) | Communication line fails before function processing is complete between Altibase CLI driver and DB. |
| HY000 | General error |
Related Functions#
SQLBindCol
SQLBindFileToParam
SQLDescribeCol
SQLFetch
Examples#
It is assumed that a table has been created with the following DDL.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 BLOB);
Write one LOB to a file.#
SQLCHAR fileName[16];
SQLLEN fileNameLength = 15;
SQLUINTEGER fileOptions = SQL_FILE_CREATE;
SQLLEN valueLength;
.
strcpy(query, "SELECT i2 FROM T1 WHERE i1=1");
if (SQLPrepare(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLPrepare : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* Specify a file to put the result values of Select. */
strcpy(fileName, "Terminator2.avi");
if (SQLBindFileToCol(stmt, 1, fileName, &fileNameLength, &fileOptions, 16, &valueLength) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLBindFileToCol : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecute : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLFetch(stmt) == SQL_SUCCESS)
{
printf("SQLFetch success!!!\n");
}
else
{
execute_err(dbc, stmt, “SQLFetch : “);
}
Write three LOB’s to a file#
SQLCHAR fileName[3][10];
SQLLEN fileNameLength[3];
SQLUINTEGER fileOptions[3];
SQLLEN valueLength[3];
.
.
.
if (SQLSetStmtAttr(stmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) 3, 0) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLSetStmtAttr : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLSetStmtAttr(stmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLSetStmtAttr : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
strcpy(query, "SELECT i2 FROM T1 WHERE i1 >= 1 AND i1 <= 3");
if (SQLExecDirect(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecDirect : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* Specify a file to put the result values of Select. */
strcpy(fileName[0], "Cube.avi");
strcpy(fileName[1], "Movie.avi");
strcpy(fileName[2], "Term.avi");
for (i = 0; i < 3; i++)
{
fileNameLength[i] = strlen(fileName[i]);
fileOptions[i] = SQL_FILE_CREATE;
}
if (SQLBindFileToCol(stmt, 1, (SQLCHAR *) fileName, fileNameLength, fileOptions, 10, valueLength) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLBindFileToCol : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLFetch(stmt) == SQL_SUCCESS)
{
printf("SQLFetch success!!!\n");
}
else
{
execute_err(dbc, stmt, “SQLFetch : “);
Write n LOB’s to a file#
SQLCHAR fileName[11];
SQLLEN fileNameLength = 10;
SQLUINTEGER fileOptions = SQL_FILE_OVERWRITE;
SQLLEN valueLength;
.
strcpy(query, "SELECT i2 FROM T1");
if (SQLExecDirect(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecDirect : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindFileToCol(stmt, 1, fileName, &fileNameLength, &fileOptions, 11, &valueLength) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLBindFileToCol : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
for (i = 0; ; i++)
{
sprintf(fileName, "Term%02d.avi", i + 1);
rc = SQLFetch(stmt);
if (rc == SQL_SUCCESS)
{
printf("SQLFetch of file[%02] success!!!\n", i + 1);
}
else if (rc == SQL_NO_DATA)
{
break;
}
else
{
execute_err(dbc, stmt, "SQLFetch : ");
break;
}
}
SQLindFileToParam#
SQLBindFileToParam binds the parameter market ‘?’ used for LOB data type to a file or files. When SQLExecute() or SQLExecDirect() is called, data is transferred from the file(s) to the database management system.
Syntax#
SQLRETURN SQLBindFileToParam(
SQLHSTMT stmt,
SQLSMALLINT par,
SQLSMALLINT sqlType,
SQLCHAR * fileName,
SQLLEN * fileNameLength,
SQLUINTEGER * fileOptions,
SQLLEN maxFileNameLength,
SQLLEN * ind);
Arguments#
| Data Type | Argument | In/Output | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | A handle for the found results. |
| SQLSMALLINT | Par | Input | The order of parameters. Begins at 1. |
| SQLSMALLINT | sqlType | Input | The SQL data type of a parameter.The following options are available: SQL_BLOB SQL_CLOB |
| SQLCHAR * | fileName | Input(Pending ) | A pointer to the buffer that holds a filename or an array of filenames. Upon SQLExecute() or SQLExecDirect(), there should be a filename stored in this buffer. Either of an absolute path (recommended) and a relative path is allowed. This argument cannot be NULL. |
| SQLLEN * | fileNameLength | Input(Pending) | A pointer to the buffer that holds a filename length or an array of filename lengths.Upon SQLExecute() or SQLExecDirect(), there should be a filename length stored in this buffer.If this argument is NULL, a filename is regarded as a null-terminated string. That is, it has the same effect as if SQL_NTS were stored in the memory pointed by this argument.The max. length of a filename is 255 characters. |
| SQLUINTEGER * | fileOptions | Input(Pending) | A pointer to the buffer that holds a file option or an array of file options. Upon SQLExecute() or SQLExecDirect(), there should a file option stored in this buffer.The following option is available: SQL_FILE_READ. |
| SQLLEN | fileNameBufferSize | Input | The length of the filename buffer. |
| SQLLEN * | Ind | Input(Pending ) | A pointer to the buffer that holds an indicator variable or an array of indicator variables. It cannot be NULL.It is used to determine if LOB is NULL.The following values can be set for the buffer pointed by this pointer: 0, SQL_NULL_DATA. |
Result Values#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
Description#
SQLBindFileToParam() binds a LOB parameter marker to a file. SQLBindParameter() can be used to bind a parameter marker to an application variable (memory buffer). For SQLBindFileToParam() and SQLBindParameter(), only the binding by the most recently called bind function is valid.
Because the values of fileName, fileNameLength, fileOptions and ind arguments are referred to upon SQLExecute() or SQLExecDirect(), they should be set before SQLExecute() or SQLExecDirect() is called. When SQLExecute() or SQLExecDirect() is called, data is transferred from the file being bound to DBMS.
If LOB is NULL, the buffer pointed by the ind pointer should be set to SQL_NULL_DATA, and then SQLExecute() or SQLExecDirect() should be called. If LOB is not NULL, the buffer pointed by the ind pointer should be set to 0. The ind argument cannot be a NULL pointer.
To bind an array of files to a parameter marker, all of the fileName, fileNameLength, fileOptions and ind arguments should be arrays.
Diagnosis#
| SQLSTATE | Description | Comments |
|---|---|---|
| 08S01 | Communication link fault (Data transmission failure) | Communication link failed before function processing is complete between Altibase CLI driver and DB |
| HY000 | General error |
Related Functions#
SQLBindCol
SQLBindFileToCol
SQLExecute
SQLExecDirect
SQLDescribeParam
Examples#
It is assumed that a table has been created with the following DDL.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 BLOB);
Input one LOB to a table#
SQLCHAR fileName[16];
SQLLEN fileNameLength = 15;
SQLUINTEGER fileOptions = SQL_FILE_READ;
SQLLEN ind = 0;
.
strcpy(query, "INSERT INTO T1 VALUES (1, ?)");
/* Prepare a statement and bind a file */
if (SQLPrepare(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLPrepare : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
strcpy(fileName, "Terminator2.avi");
if (SQLBindFileToParam(stmt, 1, SQL_BLOB, fileName, &fileNameLength, &fileOptions, 16, &ind) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLBindFileToParam : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecute : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
Input three LOB’s to a table#
SQLINTEGER i1[3];
SQLCHAR fileName[3][10];
SQLLEN fileNameLength[3];
SQLUINTEGER fileOptions[3];
SQLLEN ind[3];
.
if (SQLSetStmtAttr(stmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) 3, 0) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLSetStmtAttr : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLSetStmtAttr(stmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLSetStmtAttr : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
strcpy(query, "INSERT INTO T1 VALUES (?, ?)");
/* Prepare a statement and bind a file. */
if (SQLPrepare(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLPrepare : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_INTEGER, SQL_INTEGER, 0, 0, (SQLPOINTER) i1, 0, NULL) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLBindParameter : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindFileToParam(stmt, 2, SQL_BLOB, (SQLCHAR *) fileName, fileNameLength, fileOptions, 10, ind) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLBindFileToParam : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* Specify a file to insert data. */
strcpy(fileName[0], "Cube.avi");
strcpy(fileName[1], "Movie.avi");
strcpy(fileName[2], "Term.avi");
for (i = 0; i < 3; i++)
{
i1[i] = i + 1;
fileNameLength[i] = strlen(fileName[i]);
fileOptions[i] = SQL_FILE_READ;
ind[i] = 0;
}
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecute : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
Update one LOB in a table#
SQLCHAR fileName[16];
SQLLEN fileNameLength = 15;
SQLUINTEGER fileOptions = SQL_FILE_READ;
SQLLEN ind = 0;
.
strcpy(query, "UPDATE T1 SET i2=? WHERE i1=1");
/* Prepare a statement and bind a file. */
if (SQLPrepare(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLPrepare : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
strcpy(fileName, "Terminator2_fix.avi");
if (SQLBindFileToParam(stmt, 1, SQL_BLOB, fileName, &fileNameLength, &fileOptions, 16, &ind) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLBindFileToParam : “);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, "SQLExecute : ");
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
SQLGetLobLength#
SQLGetLobLength gets the length of the LOB pointed by the LOB locator obtained during the current transaction.
Syntax#
SQLRETURN SQLGetLobLength(
SQLHSTMT stmt,
SQLUBIGINT locator,
SQLSMALLINT locatorCType,
SQLUINTEGER * valueLength);
Arguments#
| Data Type | Argument | In/Output | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | A handle for the found results. |
| SQLUBIGINT | locator | Input | LOB Locator |
| SQLSMALLINT | locatorCType | Input | The C data type of A LOB locator. It can have the following values: SQL_C_BLOB_LOCATOR SQL_C_CLOB_LOCATOR |
| SQLUINTEGER * | valueLength | Output | It stores the length of a LOB. The buffer pointed to by the pointer returns the data length. |
Return Values#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
Description#
A function that is used to get the length of the LOB pointed by a LOB locator.
A LOB locator has the value that directly points LOB in a database (not offset in LOB). A LOB locator can be obtained in two ways:
It can be obtained from the LOB column in the result set of the SELECT SQL statement with SQLBindCol() or SQLGetData() function.
In this case, the application buffer type bound by the user should be SQL_C_CLOB_LOCATOR or SQL_C_BLOB_LOCATOR.
It can be obtained from the output parameter of SQLBindParameter().
In this case, the application buffer type bound by the user should be SQL_C_CLOB_LOCATOR or SQL_C_BLOB_LOCATOR.
If a LOB locator has not been obtained during the current transaction, it cannot be used as an argument for this function. This is because a LOB locator becomes invalid if a transaction is terminated. If an invalid LOB locator is used as an argument, this function will return SQL_ERROR, and the buffer pointed by the valueLength argument will not be changed.
The length of LOB is returned via the valueLength argument. However, If a LOB locator points NULL LOB, SQL_NULL_DATA is returned to the buffer pointed by the valueLength argument. If a LOB locator points NULL LOB, this function will not return an error.
Diagnosis#
| SQLSTATE | Description | Note |
|---|---|---|
| 08S01 | Communication link fault (Data transmission failure) | Communication link failed before function processing is complete between Altibase CLI driver and DB. |
| HY000 | General error |
Related Functions#
SQLBindCol
SQLBindParameter
SQLFetch
SQLExecute
SQLGetLob
SQLPutLob
Example#
It is assumed that a table has been created with the following DDL.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 BLOB);
Retrieve the length of LOB data#
SQLINTEGER valueLength;
SQLUBIGINT lobLoc;
.
.
.
strcpy(query, "SELECT i2 FROM T1 WHERE i1=1");
if (SQLExecDirect(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLExecDirect : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
if (SQLBindCol(stmt, 1, SQL_C_BLOB_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;
}
if (SQLGetLobLength(stmt, lobLoc, SQL_C_BLOB_LOCATOR, &valueLength) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLGetLobLength : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
printf("SQLGetLobLength success!!!\n");
if (SQLFreeLob(stmt, lobLoc) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLFreeLob : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
SQLGetLob#
SQLGetLob gets a part of data in the LOB pointed by the LOB locator obtained during the current transaction to an application data buffer.
Syntax#
SQLRETURN SQLGetLob(
SQLHSTMT stmt,
SQLSMALLINT locatorCType,
SQLUBIGINT sourceLocator,
SQLUINTEGER fromPosition,
SQLUINTEGER forLength,
SQLSMALLINT targetCType,
SQLPOINTER value,
SQLUINTEGER bufferSize,
SQLUINTEGER * valueLength);
Arguments#
| Data Type | Argument | In/Output | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | Handle for the found results. |
| SQLSMALLINT | locatorCType | Input | The C data type identifier of a LOB locator. It can have the following values: SQL_C_BLOB_LOCATOR SQL_C_CLOB_LOCATOR |
| SQLUBIGINT | sourceLocator | Input | Source LOB Locator |
| SQLUINTEGER | fromPosition | Input | The start point of data to transfer from LOB (byte). It begins at 1. |
| SQLUINTEGER | forLength | Input | The length of data to transfer from LOB (byte). |
| SQLSMALLINT | targetCType | Input | The C data type identifier of the value buffer. It can have the following values: SQL_C_BINARY SQL_C_CHAR If the user reads BLOB data into the SQL_C_CHAR buffer, BINARY is converted to CHAR, and the result value is stored in an application buffer. |
| SQLPOINTER | value | Output | A pointer to the buffer that holds data. |
| SQLUINTEGER | bufferSize | Input | The size of the value buffer (byte). |
| SQLUINTEGER* | valueLength | Output | A pointer to the buffer to which the length of data stored in the value buffer is returned. This argument cannot be NULL. |
Result Values#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
Description#
Gets a part of data in the LOB pointed by the source locator to an application data buffer. It is used to get LOB data in parts. The total length of LOB can be obtained by calling SQLGetLobLength().
If a source locator is not the LOB locator obtained during the current transaction, it cannot be used as an argument for this function. This is because a LOB locator becomes invalid if a transaction is terminated. If a source LOB locator is not valid, the SQLGetLob() function will return SQL_ERROR, and the buffer pointed by the value and valueLength arguments will not be changed.
If a source locator points NULL LOB, the SQLGetLob() function works in the same way as when a LOB locator points LOB with length 0.
If the size of data that will be returned by calling SQLGetLob() exceeds the size of bufferSize, the SQLGetLob() will return SQL_SUCCESS_WITH_INFO (SQLSTATE=01004), and the data will be truncated to fit the buffer size before it is returned to the buffer.
Diagnosis#
| SQLSTATE | Description | Comments |
|---|---|---|
| 08S01 | Communication link fault (Data transmission failure) | Communication link failed before function processing is complete between Altibase CLI driver and DB. |
| HY000 | General error |
Related Functions#
SQLGetLobLength
SQLPutLob
Example#
It is assumed that a table has been created with the following DDL.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 CLOB);
Retrieve LOB data to an application buffer by using the SQLGetLob() function#
SQLCHAR buf[1024];
SQLINTEGER valueLength, accumLength, forLength, procLength;
SQLUBIGINT lobLoc;
.
.
strcpy(query, "SELECT i2 FROM T1 WHERE i1=1");
if (SQLExecDirect(stmt, query, SQL_NTS) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLExecDirect : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
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;
}
if (SQLGetLobLength(stmt, lobLoc, SQL_C_CLOB_LOCATOR, &valueLength) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLGetLobLength : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
for (accumLength = 0; accumLength < valueLength; accumLength += procLength)
{
if (valueLength - accumLength > 256)
{
forLength = 256;
}
else
{
forLength = valueLength - accumLength;
}
if (SQLGetLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, accumLength, forLength, SQL_C_CHAR, buf, 256, &procLength) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLGetLob : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
printf("%s", buf);
}
if (SQLFreeLob(stmt, lobLoc) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLFreeLob : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
SQLPutLob#
All operations of this function are performed as internal updates. Insertion is the operation of updating existing LOB data of 0 length value into another value. Depending on the argument value, update either overwrites existing data with another value, starting at a specified position, or appends another value at the end of existing data.
Syntax#
SQLRETURN SQLPutLob(
SQLHSTMT stmt,
SQLSMALLINT locatorCType,
SQLUBIGINT targetLocator,
SQLUINTEGER fromPosition,
SQLUINTEGER forLength,
SQLSMALLINT sourceCType,
SQLPOINTER value,
SQLUINTEGER valueLength);
Arguments#
| Data Type | Argument | In/Output | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | Handle for the found results. |
| SQLSMALLINT | locatorCType | Input | The C data type of a target LOB locator. SQL_C_BLOB_LOCATOR SQL_C_CLOB_LOCATOR |
| SQLUBIGINT | targetLocator | Input | Target LOB Locator |
| SQLUINTEGER | fromPosition | Input | The start point to update data in LOB (byte). It begins at 1. |
| SQLUINTEGER | forLength | Input | Not used. |
| SQLSMALLINT | sourceCType | Input | The C data type identifier of the value buffer. SQL_C_BINARY (for BLOB), SQL_C_CHAR (for CLOB) |
| SQLPOINTER | value | Input | The pointer that points to the buffer storing input data. |
| SQLUINTEGER | valueLength | Input | The length of data input in the value buffer (unit: bytes). A value larger than 0 must be set; SQL_NULL_DATA is not accepted. |
Return Values#
SQL_SUCCESS
SQL_SUCCESS_WITH_INFO
SQL_INVALID_HANDLE
SQL_ERROR
Description#
This function inserts or updates data stored in the application data buffer into the LOB which the target LOB locator points to.
When this function is operated, the server overwrites data of the target LOB, starting at the position of fromPosition, for the length of valueLength of the value buffer. If valueLength is larger than (LOBSize - fromPosition), the length of the target LOB of the database is extended; if fromPosition points to the end position of the target LOB value, data of the length of valueLength of the value buffer is appended to the end of the existing value.
If the LOB locator is not one which is opened in the current session, it is not accepted as an argument for this function, since the LOB locator becomes invalid when the transaction terminates. If the target LOB locator is invalid, the SQLPutLob() function returns SQL_ERROR.
If the target LOB locator points to a LOB with the value of NULL, the SQLPutLob() function operates equivalent to the LOB locator pointing to a LOB with the length of 0.
The fromPosition argument must not be larger than the length of the target LOB at the time point of calling. If the value of the fromPosition argument is larger than the length of the target LOB, the SQLPutLob() function returns SQL_ERROR.
Diagnosis#
| SQLSTATE | Description | Comments |
|---|---|---|
| 08S01 | Communication link fault (Data transmission failure) | Communication link failed before function processing is complete between Altibase CLI driver and DB. |
| HY000 | 일반 오류 |
Related Functions#
SQLGetLobLength
SQLGetLob
Examples#
It is assumed that a table has been created with the following DDL.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 CLOB);
After inserting a record with the CLOB column value being ‘Ver.Beta’, replace ‘Beta’ with ‘Gamma’#
SQLCHAR buf[5];
SQLUBIGINT lobLoc;
.
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;
}
.
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;
}
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;
}
memcpy(buf, "Gamma", 5);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 4, 4, 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;
}
Insert a record with the CLOB column value being ‘Ver.0.9a’#
SQLCHAR buf[8];
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;
}
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;
}
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLExecute : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
memcpy(buf, "Ver.0.9a", 8);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 0, 0, SQL_C_CHAR, buf, 7) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLPutLob : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
/* In ‘Ver.0.9a’, replace ‘0.9’ with ‘1’. */
memcpy(buf, "1", 1);
if (SQLPutLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 4, 3, SQL_C_CHAR, buf, 1) != 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;
}
Change the CLOB of multiple records to ‘Retail’ at once#
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;
}
/* If an UPDATE query is executed after a LOB locator parameter is being outbound, LOB columns to be updated will be truncated to null automatically. */
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;
}
if (SQLExecute(stmt) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLExecute : ”);
SQLFreeStmt(stmt, SQL_DROP);
return SQL_ERROR;
}
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;
}
SQLTrimLob#
This function deletes the latter portion of data from a specified position, of the LOB value that the LOB locater points to.
Syntax#
SQLRETURN SQLTrimLob(
SQLHSTMT stmt,
SQLSMALLINT locatorCType,
SQLUBIGINT targetLocator,
SQLLEN fromPosition);
Arguments#
| Data Type | Argument | In/Output | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | The handle for the found results. |
| SQLSMALLINT | locatorCType | Input | The C data type identifier of the target LOB locator. SQL_C_BLOB_LOCATOR SQL_C_CLOB_LOCATOR |
| SQLUBIGINT | targetLocator | Input | Target LOB Locator |
| SQLLEN | fromPosition | Input | The position at which to start deleting LOB data (unit:bytes). Begins at 0. |
Result Values#
SQL_SUCCESS
SQL_INVALID_HANDLE
SQL_ERROR
Description#
This function deletes the latter portion of data from a specified position, of the LOB value that the LOB locater points to. After deletion, the length of the target LOB is shortened.
If the LOB locator is not one which is opened in the current session, it is not accepted as an argument for this function, since the LOB locator becomes invalid when the transaction terminates. If the target LOB locator is invalid, the SQLTrimLob() function returns SQL_ERROR.
Diagnosis#
| SQLSTATE | Description | Comments |
|---|---|---|
| 08S01 | Communication link fault (Data transmission failure) | A communication link failed before function processing is complete between Altibase CLI driver and DB. |
| HY000 | General error |
Related Functions#
SQLGetLobLength
SQLGetLob
Examples#
It is assumed that a table is created with the following DDL.
CREATE TABLE T1 (i1 INTEGER PRIMARY KEY, i2 CLOB);
After inserting a record with the CLOB column value ‘Ver.Beta’, delete ‘Beta’#
SQLCHAR buf[5];
SQLUBIGINT lobLoc;
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;
}
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;
}
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;
}
if (SQLTrimLob(stmt, SQL_C_CLOB_LOCATOR, lobLoc, 4) != SQL_SUCCESS)
{
execute_err(dbc, stmt, “SQLTrimLob : ”);
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;
}
SQLFreeLob#
SQLFreeLob releases resources that are related to a LOB locator opened during the current transaction.
Syntax#
SQLRETURN SQLFreeLob (
SQLHSTMT stmt,
SQLUBIGINT locator);
Arguments#
| Data Type | Argument | In/Out | Description |
|---|---|---|---|
| SQLHSTMT | stmt | Input | Handle for the found results |
| SQLUBIGINT | locator | Input | LOB Locator |
Return Values#
SQL_SUCCESS
SQL_INVALID_HANDLE
SQL_ERROR
Description#
Reports that operation of LOB pointed by a LOB locator is complete. This will release the LOB locator assigned by a server and other related resources in the server.
This function does not commit or rollback changes to LOB pointed by a LOB locator.
If a transaction is terminated with SQLEndTran(), a LOB locator is automatically released and this function does have to be called.
Diagnosis#
| SQLSTATE | Description | Comments |
|---|---|---|
| 08S01 | Communication link fault (Data transmission failure) | Communication link failed before function processing is complete between Altibase CLI driver and DB. |
| HY000 | General error |
Related Functions#
SQLGetLobLength
SQLGetLob
SQLPutLob
Example#
Please see the examples of SQLGetLobLength(), SQLGetLob() and SQLPutLob().