Example of retrieving a smart large object from the database using ifx_lo functions
The code example, loselect.c, shows how to retrieve a smart large object from the database.
You can find the loselect.c file
in the %INFORMIXDIR%/demo/clidemo directory on UNIX™ platforms and in the %INFORMIXDIR%\demo\odbcdemo directory
on Windows™ platforms. You
can also find instructions on how to build the odbc_demo database
in the same location.
/*
** loselect.c
**
** To access a smart large object
** SQLBindCol
** SQLBindParameter
** SQLConnect
** SQLFetch
** SQLFreeStmt
** SQLGetInfo
** SQLDisconnect
** SQLExecDirect
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef NO_WIN32
#include <io.h>
#include <windows.h>
#include <conio.h>
#endif /*NO_WIN32*/
#include "infxcli.h"
#define ERRMSG_LEN 200
UCHAR defDsn[] = "odbc_demo";
int checkError (SQLRETURN rc,
SQLSMALLINT handleType,
SQLHANDLE handle,
char *errmsg)
{
SQLRETURN retcode = SQL_SUCCESS;
SQLSMALLINT errNum = 1;
SQLCHAR sqlState[6];
SQLINTEGER nativeError;
SQLCHAR errMsg[ERRMSG_LEN];
SQLSMALLINT textLengthPtr;
if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
{
while (retcode != SQL_NO_DATA)
{
retcode = SQLGetDiagRec (handleType, handle, errNum, sqlState,
&nativeError, errMsg, ERRMSG_LEN, &textLengthPtr);
if (retcode == SQL_INVALID_HANDLE)
{
fprintf (stderr, "checkError function was called with an
invalid handle!!\n");
return 1;
}
if ((retcode == SQL_SUCCESS) || (retcode ==
SQL_SUCCESS_WITH_INFO))
fprintf (stderr, "ERROR: %d: %s : %s \n", nativeError,
sqlState, errMsg);
errNum++;
}
fprintf (stderr, "%s\n", errmsg);
return 1; /* all errors on this handle have been reported */
}
else
return 0; /* no errors to report */
}
int main (long argc,
char *argv[])
{
/* Declare variables
*/
/* Handles */
SQLHDBC hdbc;
SQLHENV henv;
SQLHSTMT hstmt;
/* Smart large object file descriptor */
long lofd;
long lofd_valsize = 0;
/* Smart large object pointer structure */
char* loptr_buffer;
short loptr_size;
long loptr_valsize = 0;
/* Smart large object status structure */
char* lostat_buffer;
short lostat_size;
long lostat_valsize = 0;
/* Smart large object data */
char* lo_data;
long lo_data_valsize = 0;
/* Miscellaneous variables */
UCHAR dsn[20]; /*name of the DSN used for connecting to the
database*/
SQLRETURN rc = 0;
int in;
char* selectStmt = "SELECT advert FROM item WHERE item_num =
1004";
long mode = LO_RDONLY;
long lo_size;
long cbMode = 0, cbLoSize = 0;
/* STEP 1. Get data source name from command line (or use default)
** Allocate the environment handle and set ODBC version
** Allocate the connection handle
** Establish the database connection
** Allocate the statement handle
*/
/* If(dsn is not explicitly passed in as arg) */
if (argc != 2)
{
/* Use default dsn - odbc_demo */
fprintf (stdout, "\nUsing default DSN : %s\n", defDsn);
strcpy ((char *)dsn, (char *)defDsn);
}
else
{
/* Use specified dsn */
strcpy ((char *)dsn, (char *)argv[1]);
fprintf (stdout, "\nUsing specified DSN : %s\n", dsn);
}
/* Allocate the Environment handle */
rc = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (rc != SQL_SUCCESS)
{
fprintf (stdout, "Environment Handle Allocation
failed\nExiting!!\n");
return (1);
}
/* Set the ODBC version to 3.5 */
rc = SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3, 0);
if (checkError (rc, SQL_HANDLE_ENV, henv, "Error in Step 1 --
SQLSetEnvAttr failed\nExiting!!\n"))
return (1);
/* Allocate the connection handle */
rc = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
if (checkError (rc, SQL_HANDLE_ENV, henv, "Error in Step 1 -- Connection
Handle Allocation failed\nExiting!!\n"))
return (1);
/* Establish the database connection */
rc = SQLConnect (hdbc, dsn, SQL_NTS, "", SQL_NTS, "", SQL_NTS);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 1 -- SQLConnect
failed\nExiting!!"))
return (1);
/* Allocate the statement handle */
rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 1 -- Statement
Handle Allocation failed\nExiting!!"))
return (1);
fprintf (stdout, "STEP 1 done...connected to database\n");
/* STEP 2. Select a smart-large object from the database
** -- the select statement executed is -
** "SELECT advert FROM item WHERE item_num = 1004"
*/
/* Execute the select statement */
rc = SQLExecDirect (hstmt, selectStmt, SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 2 --
SQLExecDirect failed\n"))
goto Exit;
fprintf (stdout, "STEP 2 done...select statement executed...smart large
object retrieved from the databse\n");
/* STEP 3. Get the size of the smart large object pointer structure.
** Allocate a buffer to hold the structure.
** Get the smart large object pointer structure from the
** database.
** Close the result set cursor.
*/
/* Get the size of the smart large object pointer structure */
rc = SQLGetInfo (hdbc, SQL_INFX_LO_PTR_LENGTH, &loptr_size,
sizeof(loptr_size),
NULL);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 3 -- SQLGetInfo
failed\n"))
goto Exit;
/* Allocate a buffer to hold the smart large object pointer structure */
loptr_buffer = malloc (loptr_size);
/* Bind the smart large object pointer structure buffer allocated to the
column in the result set & fetch it from the database */
rc = SQLBindCol (hstmt, 1, SQL_C_BINARY, loptr_buffer, loptr_size,
&loptr_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 --
SQLBindCol failed\n"))
goto Exit;
rc = SQLFetch (hstmt);
if (rc == SQL_NO_DATA_FOUND)
{
fprintf (stdout, "No Data Found\nExiting!!\n");
goto Exit;
}
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 -- SQLFetch
failed\n"))
goto Exit;
/* Close the result set cursor */
rc = SQLCloseCursor (hstmt);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 3 --
SQLCloseCursor failed\n"))
goto Exit;
fprintf (stdout, "STEP 3 done...smart large object pointer structure
fetched from the database\n");
/* STEP 4. Use the smart large object's pointer structure to open it
** and obtain the smart large object file descriptor.
** Reset the statement parameters.
*/
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_LONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 4 --
SQLBindParameter failed (param 1)\n"))
goto Exit;
rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)loptr_size, 0, loptr_buffer,
loptr_size, &loptr_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 4 --
SQLBindParameter failed (param 2)\n"))
goto Exit;
rc = SQLBindParameter (hstmt, 3, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, (UDWORD)0, 0, &mode, sizeof(mode), &cbMode);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 4 --
SQLBindParameter failed (param 3)\n"))
goto Exit;
rc = SQLExecDirect (hstmt, "{? = call ifx_lo_open(?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 4 --
SQLExecDirect failed\n"))
goto Exit;
/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 4 --
SQLFreeStmt failed\n"))
goto Exit;
fprintf (stdout, "STEP 4 done...smart large object opened... file
descriptor obtained\n");
/* STEP 5. Get the size of the smart large object status structure.
** Allocate a buffer to hold the structure.
** Get the smart large object status structure from the
** database.
** Reset the statement parameters.
*/
/* Get the size of the smart large object status structure */
rc = SQLGetInfo (hdbc, SQL_INFX_LO_STAT_LENGTH, &lostat_size,
sizeof(lostat_size), NULL);
if (checkError (rc, SQL_HANDLE_DBC, hdbc, "Error in Step 5 -- SQLGetInfo
failed\n"))
goto Exit;
/* Allocate a buffer to hold the smart large object status structure. */
lostat_buffer = malloc(lostat_size);
/* Get the smart large object status structure from the database. */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLBindParameter failed (param 1)\n"))
goto Exit;
rc = SQLBindParameter (hstmt, 2, SQL_PARAM_INPUT_OUTPUT, SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)lostat_size, 0, lostat_buffer,
lostat_size, &lostat_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLBindParameter failed (param 2)\n"))
goto Exit;
rc = SQLExecDirect (hstmt, "{call ifx_lo_stat(?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLExecDiret failed\n"))
goto Exit;
/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 5 --
SQLFreeStmt failed\n"))
goto Exit;
fprintf (stdout, "STEP 5 done...smart large object status structure
fetched from the database\n");
/* STEP 6. Use the smart large object's status structure to get the
** size of the smart large object.
** Reset the statement parameters.
*/
/* Use the smart large object status structure to get the size of the
smart large object */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_BINARY,
SQL_INFX_UDT_FIXED, (UDWORD)lostat_size, 0, lostat_buffer,
lostat_size, &lostat_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLBindParameter failed (param 1)\n"))
goto Exit;
rc = SQLBindParameter (hstmt, 2, SQL_PARAM_OUTPUT, SQL_C_LONG,
SQL_BIGINT, (UDWORD)0, 0, &lo_size, sizeof(lo_size), &cbLoSize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLBindParameter failed (param 1)\n"))
goto Exit;
rc = SQLExecDirect (hstmt, "{call ifx_lo_stat_size(?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLExecDirect failed\n"))
goto Exit;
/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 6 --
SQLFreeStmt failed\n"))
goto Exit;
fprintf (stdout, "STEP 6 done...smart large object size = %ld bytes\n",
lo_size);
/* STEP 7. Allocate a buffer to hold the smart large object's data.
** Read the smart large object's data using its file descriptor.
** Null-terminate the last byte of the smart large-object's data.
** Print out the contents of the smart large object.
** Reset the statement parameters.
*/
/* Allocate a buffer to hold the smart large object's data chunks */
lo_data = malloc (lo_size + 1);
/* Read the smart large object's data */
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLBindParameter failed (param 1)\n"))
goto Exit;
rc = SQLBindParameter (hstmt, 2, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_CHAR,
lo_size, 0, lo_data, lo_size, &lo_data_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLBindParameter failed (param 2)\n"))
goto Exit;
rc = SQLExecDirect (hstmt, "{call ifx_lo_read(?, ?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLExecDirect failed\n"))
goto Exit;
/* Null-terminate the last byte of the smart large objects data */
lo_data[lo_size] = '\0';
/* Print the contents of the smart large object */
fprintf (stdout, "Smart large object contents are.....\n\n\n%s\n\n\n",
lo_data);
/* Reset the statement parameters */
rc = SQLFreeStmt (hstmt, SQL_RESET_PARAMS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 7 --
SQLFreeStmt failed\n"))
goto Exit;
fprintf (stdout, "STEP 7 done...smart large object read completely\n");
/* STEP 8. Close the smart large object.
*/
rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG,
SQL_INTEGER, (UDWORD)0, 0, &lofd, sizeof(lofd), &lofd_valsize);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 8 --
SQLBindParameter failed\n"))
goto Exit;
rc = SQLExecDirect (hstmt, "{call ifx_lo_close(?)}", SQL_NTS);
if (checkError (rc, SQL_HANDLE_STMT, hstmt, "Error in Step 8 --
SQLExecDirect failed\n"))
goto Exit;
fprintf (stdout, "STEP 8 done...smart large object closed\n");
/* STEP 9. Free the allocated buffers.
*/
free (loptr_buffer);
free (lostat_buffer);
free (lo_data);
fprintf (stdout, "STEP 9 done...smart large object buffers freed\n");
Exit:
/* CLEANUP: Close the statement handle
** Free the statement handle
** Disconnect from the datasource
** Free the connection and environment handles
** Exit
*/
/* Close the statement handle */
SQLFreeStmt (hstmt, SQL_CLOSE);
/* Free the statement handle */
SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
/* Disconnect from the data source */
SQLDisconnect (hdbc);
/* Free the environment handle and the database connection handle */
SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
SQLFreeHandle (SQL_HANDLE_ENV, henv);
fprintf (stdout,"\n\nHit <Enter> to terminate the program...\n\n");
in = getchar ();
return (rc);
}