/**********************************************************************
* FILENAME : WritingSingleLongTextFields.c
*
DESCRIPTION :
* Example mainly illustrates use of Data at Execution and SQLPutData ()
* to insert a record which has a long 'text' field.
*
*
* ODBC USAGE :
*
* SQLPrepare () - to prepare statement for selected table
* SQLNumParams () - to establish how many parameters are needed
* Asks for how many records are to be written
* For TestTBL1 and TestTBL2
* Uses SQLBindParam () to bind the 4 paramaters
* For each record,
* prompts for data.
* calls SQLExecute () to execute the insert
* For TestTBL3 and TestTBL4
* Uses SQLDescribeParam () to get paramater attributes
* Uses SQLBindParameter () to bind the paramater with
* overall param size and, using SQL_LEN_DATA_AT_EXEC,
* the size of the chunks to be written each time when
* execute asks for more data.
* For each record,
* calls SQLExecute () to execute the insert
* Checks for SQL_NEED_DATA and calls SQLParamData ()
* to find out which of the text paramaters needs more
* data.
* While SQL_NEED_DATA returned,
* calls SQLPutData () to write data in chunks
* call SQLParamData () which will complete the
* current parameter and return a new param ID
* and SQL_NEED_DATA if any more paramaters need
* more data (e.g. the second Memo paramater).
*
* Use CreateTable to create TestTBL3 and/or TestTBL4
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sql.h>
#include <sqlext.h>
#include <string.h>
#include "util.c"
#define MEMO1TEXTSIZE 12000
#define MEMO2TEXTSIZE 12000
#define MAXBUFLEN 256
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
void Cleanup() {
if (hstmt != SQL_NULL_HSTMT)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
if (hdbc != SQL_NULL_HDBC) {
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
int main () {
RETCODE retcode;
// SQLBindParameter variables.
SQLLEN lenTextSize, lbytes;
// SQLParamData variable.
PTR pParamID;
// SQLPutData text data.
UCHAR Memo1Data[] =
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
"abcdefghijklmnopqrstuvwxyz";
SDWORD lenBatch = (SDWORD)sizeof(Memo1Data) - 1;
// Create table ?
char table[256];
char confirm='N';
char reply=' ';
// Allocate the ODBC environment and save handle.
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
CHECK_ERROR(retcode, "SQLAllocHandle (SQL_HANDLE_STMT)", henv, SQL_HANDLE_ENV);
// Notify ODBC that this is an ODBC 3.0 app.
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
CHECK_ERROR(retcode, "SQLSetEnvAttr (SQL_ATTR_ODBC_VERSION)", henv, SQL_HANDLE_ENV);
// Allocate ODBC connection handle and connect.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
CHECK_ERROR(retcode, "SQLAllocHandle (SQL_HANDLE_DBC)", hdbc, SQL_HANDLE_DBC);
retcode=SQLDriverConnect(hdbc, NULL, "DSN=DATASOURCE;", SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
CHECK_ERROR(retcode, "SQLDriverConnect (DATASOURCE)", hdbc, SQL_HANDLE_DBC);
// Allocate statement handle.
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
CHECK_ERROR(retcode, "SQLAllocHandle (SQL_HANDLE_STMT)", hstmt, SQL_HANDLE_STMT);
// Set parameters based on total data to send.
lbytes = (SDWORD)MEMO1TEXTSIZE; //12000
lenTextSize = SQL_LEN_DATA_AT_EXEC(lbytes);
printf ("lbytes %i\n", (int)lbytes);
printf ("lenTextSize %i\n", (int)lenTextSize);
// Bind the parameter marker.
retcode = SQLBindParameter (hstmt, // hstmt
1, // Parameter Number
SQL_PARAM_INPUT, // Input/Output Type
SQL_C_CHAR, // Value Type
SQL_LONGVARCHAR, // Parameter Type
lbytes, // Column Size
0, // Decimal Digits
(VOID *)1, // Parameter Value Pointer
0, // Buffer Length
&lenTextSize); // Len or Indicator Pointer
CHECK_ERROR(retcode, "SQLAllocHandle (SQL_HANDLE_STMT)", hstmt, SQL_HANDLE_STMT);
// Execute the command.
printf ("Call SQLExecDirect\n");
retcode = SQLExecDirect(hstmt, (UCHAR*)"INSERT INTO TestTBL3 VALUES('Buzz Aldrin', 56,'1957-12-30 00:00:00', ?)", SQL_NTS);
if (retcode != SQL_NEED_DATA) {
CHECK_ERROR(retcode, "SQLExecDirect (INSERT)", hstmt, SQL_HANDLE_STMT);
}
// Check to see if NEED_DATA; if yes, use SQLPutData.
printf ("First Call - SQLParamData\n");
retcode = SQLParamData(hstmt, &pParamID);
if (retcode == SQL_NEED_DATA) {
while (lbytes > lenBatch) {
printf ("SQL_NEED_DATA Call - SQLPutData : lbytes %i, lenBatch %i\n", (int)lbytes, (int)lenBatch);
SQLPutData(hstmt, Memo1Data, lenBatch);
lbytes -= lenBatch;
}
// Put final batch.
printf ("Final Call - SQLPutData : lbytes %i\n", (int)lbytes);
retcode = SQLPutData(hstmt, Memo1Data, lbytes);
CHECK_ERROR(retcode, "SQLPutData (SQL_HANDLE_STMT)", hstmt, SQL_HANDLE_STMT);
// Make final SQLParamData call.
printf ("Final Call - SQLParamData\n");
retcode = SQLParamData(hstmt, &pParamID);
CHECK_ERROR(retcode, "SQLParamData (SQL_HANDLE_STMT)", hstmt, SQL_HANDLE_STMT);
}
exit:
printf ("\nComplete.\n");
// Free handles
// Statement
if (hstmt != SQL_NULL_HSTMT)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
// Connection
if (hdbc != SQL_NULL_HDBC) {
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
}
// Environment
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
Further information