하나의 프로세스에서 DA Connection 과 TCP Connection을 동시에 사용하기
/*
* da_tcp_example2.c
*
* Created on: 2015. 4. 8.
*/
// #include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <pthread.h>
/* include sunDB ODBC header */
#include <sundb.h>
#define THREAD_CNT 2
/* struct to hold data to be passed to a thread
this shows how multiple data items can be passed to a thread */
typedef struct _argv
{
int id;
char name[32];
int argc;
char** argv;
int ret;
int conn_type;
} argv_t;
struct timeval tv_s, tv_e;
SQLHENV gsEnv[THREAD_CNT];
SQLHDBC gsDbc[THREAD_CNT];
/* User-specific Definitions */
#define BUF_LEN 100
#define MAX_COLUMN_COUNT 1024
#define SUNDB_SQL_THROW( aLabel ) \
goto aLabel;
#define SUNDB_SQL_TRY( aExpression ) \
do \
{ \
if( !(SQL_SUCCEEDED( aExpression ) ) ) \
{ \
goto SUNDB_FINISH_LABEL; \
} \
} while( 0 )
#define SUNDB_FINISH \
goto SUNDB_FINISH_LABEL; \
SUNDB_FINISH_LABEL:
/* Column structure is as follows. */
typedef struct COLUMN_STRUCT
{
SQLCHAR ColName[BUF_LEN];
SQLSMALLINT ColNameLen;
SQLSMALLINT ColType;
SQLULEN ColSize;
SQLSMALLINT ColDecimalDigits;
SQLSMALLINT ColNullablePtr;
SQLLEN ColOctetLength;
SQLINTEGER ColLeadingPrecision;
}COLUMN_STRUCT;
/* Data structure is as follows. */
typedef struct DATA_STRUCT
{
SQLLEN DataInd;
SQLSMALLINT DataType;
union
{
SQLCHAR DataChar[BUF_LEN];
SQLSMALLINT DataSmallInt;
SQLINTEGER DataInteger;
SQLBIGINT DataBigInt;
SQLREAL DataReal;
SQLDOUBLE DataDouble;
SQL_NUMERIC_STRUCT DataNumeric;
SQLBOOLEAN DataBoolean;
SQL_DATE_STRUCT DataDate;
SQL_TIME_STRUCT DataTime;
SQL_TIME_WITH_TIMEZONE_STRUCT DataTimeTZ;
SQL_TIMESTAMP_STRUCT DataTimeStamp;
SQL_TIMESTAMP_WITH_TIMEZONE_STRUCT DataTimeStampTZ;
SQL_INTERVAL_STRUCT DataInterval;
} Data;
}DATA_STRUCT;
/* Column Data structure is as follows. */
typedef struct COLUMN_DATA_STRUCT
{
COLUMN_STRUCT ColInformation;
DATA_STRUCT DataValue;
}COLUMN_DATA_STRUCT;
/* Print diagnostic record to console */
void PrintDiagnosticRecord( SQLSMALLINT aHandleType, SQLHANDLE aHandle )
{
SQLCHAR sSQLState[6];
SQLINTEGER sNaiveError;
SQLSMALLINT sTextLength;
SQLCHAR sMessageText[SQL_MAX_MESSAGE_LENGTH];
SQLSMALLINT sRecNumber = 1;
SQLRETURN sReturn;
/* SQLGetDiagRec returns the currrent values that contains error, warning */
while( 1 )
{
sReturn = SQLGetDiagRec( aHandleType,
aHandle,
sRecNumber,
sSQLState,
&sNaiveError,
sMessageText,
100,
&sTextLength );
if( sReturn == SQL_NO_DATA )
{
break;
}
SUNDB_SQL_TRY( sReturn );
printf("\n=============================================\n" );
printf("SQL_DIAG_SQLSTATE : %s\n", sSQLState );
printf("SQL_DIAG_NATIVE : %d\n", sNaiveError );
printf("SQL_DIAG_MESSAGE_TEXT : %s\n", sMessageText );
printf("=============================================\n" );
sRecNumber++;
}
return;
SUNDB_FINISH;
printf("SQLGetDiagRec() failure.\n" );
return;
}
/*
* Code that implements the conversion from little endian mode to the
* scaled integer.
*
* Please note that it is up to the application developer to implement this
* functionality. The example here is just one of the many possible ways.
*
* http://support.microsoft.com/kb/222831
*/
long strtohextoval( SQL_NUMERIC_STRUCT * aNumStr )
{
long value = 0;
int i =1;
int last =1;
int current;
int a = 0;
int b = 0;
for( i = 0; i <= 15; i++ )
{
current = (int)aNumStr->val[i];
a = current % 16; //Obtain LSD
b = current / 16; //Obtain MSD
value += last* a;
last = last * 16;
value += last* b;
last = last * 16;
}
return value;
}
/* Select funtion */
SQLRETURN testSelect( SQLHDBC aDbc )
{
SQLHSTMT sStmt = NULL;
SQLHDESC sARD = NULL;
SQLHDESC sIRD = NULL;
SQLINTEGER sState = 0;
SQLPOINTER sData = NULL;
COLUMN_DATA_STRUCT sColData[MAX_COLUMN_COUNT];
SQLSMALLINT sColCount = 0;
SQLCHAR sDataBuffer[BUF_LEN];
SQLLEN sCount = 0;
SQLRETURN sReturn;
int i = 0;
int j = 0;
int sSign = 1;
long sNumericValue = 0;
long sDivisor = 1;
float sFinalValue = 0;
SUNDB_SQL_TRY( SQLAllocHandle( SQL_HANDLE_STMT,
aDbc,
&sStmt ) );
sState = 1;
/* SQLGetStmtAttr returns the current setting of a statement attribute. */
SUNDB_SQL_TRY( SQLGetStmtAttr( sStmt,
SQL_ATTR_APP_ROW_DESC,
&sARD,
SQL_IS_POINTER,
NULL )
== SQL_SUCCESS );
SUNDB_SQL_TRY( SQLGetStmtAttr( sStmt,
SQL_ATTR_IMP_ROW_DESC,
&sIRD,
SQL_IS_POINTER,
NULL )
== SQL_SUCCESS );
/* SQLExecDirect is way to submit an SQL statement for one-time execution */
SUNDB_SQL_TRY( SQLExecDirect( sStmt,
(SQLCHAR*)"SELECT * FROM Deposit",
SQL_NTS ) );
/* SQLNumResultCols returns the number of columns in a result set. */
SUNDB_SQL_TRY( SQLNumResultCols( sStmt,
&sColCount ) );
/* SQLDescribeCol returns the result descriptor ? column name,type,
* column size, decimal digits, and nullability ? for one column in the result set. */
for( i = 1; i <= sColCount; i ++ )
{
SUNDB_SQL_TRY( SQLDescribeCol( sStmt,
i,
sColData[i].ColInformation.ColName,
BUF_LEN,
&sColData[i].ColInformation.ColNameLen,
&sColData[i].ColInformation.ColType,
&sColData[i].ColInformation.ColSize,
&sColData[i].ColInformation.ColDecimalDigits,
&sColData[i].ColInformation.ColNullablePtr ) );
SUNDB_SQL_TRY( SQLGetDescField( sIRD,
i,
SQL_DESC_OCTET_LENGTH,
&sColData[i].ColInformation.ColOctetLength,
0,
NULL )
== SQL_SUCCESS );
}
for( i = 1; i <= sColCount; i ++ )
{
/* Conversion type(SQL type -> SQL_C type), and specify variables. */
/*
* C Data Types :
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms714556%28v=vs.85%29.aspx
* Converting Data from C to SQL Data Types :
* http://msdn.microsoft.com/en-us/library/windows/desktop/ms716298%28v=vs.85%29.aspx
*/
switch( sColData[i].ColInformation.ColType )
{
case SQL_CHAR:
/* FALL_THROUGH */ /* Variables used 'SQLCHAR type' is. */
case SQL_VARCHAR:
/* FALL_THROUGH */ /* Variables used 'SQLCHAR type' is. */
case SQL_BINARY:
/* FALL_THROUGH */ /* Variables used 'SQLCHAR type' is. */
case SQL_VARBINARY:
/* FALL_THROUGH */ /* Variables used 'SQLCHAR type' is. */
case SQL_ROWID:
sColData[i].DataValue.DataType = SQL_C_CHAR;
sData = &sColData[i].DataValue.Data.DataChar;
break;
case SQL_SMALLINT: /* 'SQL_SMALLINT' type */
sColData[i].DataValue.DataType = SQL_C_SHORT;
sData = &sColData[i].DataValue.Data.DataSmallInt;
break;
case SQL_INTEGER: /* 'SQL_INTEGER' type */
sColData[i].DataValue.DataType = SQL_C_LONG;
sData = &sColData[i].DataValue.Data.DataInteger;
break;
case SQL_BIGINT: /* 'SQL_BIGINT' type */
sColData[i].DataValue.DataType = SQL_C_SBIGINT;
sData = &sColData[i].DataValue.Data.DataBigInt;
break;
case SQL_NUMERIC: /* 'SQL_NUMERIC' type */
sColData[i].DataValue.DataType = SQL_C_NUMERIC;
sData = &sColData[i].DataValue.Data.DataNumeric;
break;
case SQL_REAL: /* 'SQL_REAL' type */
sColData[i].DataValue.DataType = SQL_C_FLOAT;
sData = &sColData[i].DataValue.Data.DataReal;
break;
case SQL_DOUBLE: /* 'SQL_DOUBLE' type */
sColData[i].DataValue.DataType = SQL_C_DOUBLE;
sData = &sColData[i].DataValue.Data.DataDouble;
break;
case SQL_BOOLEAN: /* 'SQL_BOOLEAN' type */
sColData[i].DataValue.DataType = SQL_C_BOOLEAN;
sData = &sColData[i].DataValue.Data.DataBoolean;
break;
case SQL_TYPE_DATE: /* 'SQL_TYPE_DATE' type */
sColData[i].DataValue.DataType = SQL_C_TYPE_DATE;
sData = &sColData[i].DataValue.Data.DataDate;
break;
case SQL_TYPE_TIME: /* 'SQL_TYPE_TIME' type */
sColData[i].DataValue.DataType = SQL_C_TYPE_TIME;
sData = &sColData[i].DataValue.Data.DataTime;
break;
case SQL_TYPE_TIME_WITH_TIMEZONE: /* 'SQL_TYPE_TIME_WITH_TIMEZONE' type */
sColData[i].DataValue.DataType = SQL_C_TYPE_TIME_WITH_TIMEZONE;
sData = &sColData[i].DataValue.Data.DataTimeTZ;
break;
case SQL_TYPE_TIMESTAMP: /* 'SQL_TYPE_TIMESTAMP' type */
sColData[i].DataValue.DataType = SQL_C_TYPE_TIMESTAMP;
sData = &sColData[i].DataValue.Data.DataTimeStamp;
break;
case SQL_TYPE_TIMESTAMP_WITH_TIMEZONE: /* 'SQL_TYPE_TIMESTAMP_WITH_TIMEZONE' type */
sColData[i].DataValue.DataType = SQL_C_TYPE_TIMESTAMP_WITH_TIMEZONE;
sData = &sColData[i].DataValue.Data.DataTimeStampTZ;
break;
case SQL_INTERVAL_YEAR: /* 'SQL_INTERVAL_YEAR' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_YEAR;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_MONTH: /* 'SQL_INTERVAL_MONTH' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_MONTH;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_DAY: /* 'SQL_INTERVAL_DAY' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_DAY;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_HOUR: /* 'SQL_INTERVAL_HOUR' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_HOUR;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_MINUTE: /* 'SQL_INTERVAL_MINUTE' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_MINUTE;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_SECOND: /* 'SQL_INTERVAL_SECOND' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_SECOND;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_YEAR_TO_MONTH: /* 'SQL_INTERVAL_YEAR_TO_MONTH' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_YEAR_TO_MONTH;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_DAY_TO_HOUR: /* 'SQL_INTERVAL_DAY_TO_HOUR' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_DAY_TO_HOUR;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_DAY_TO_MINUTE: /* 'SQL_INTERVAL_DAY_TO_MINUTE' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_DAY_TO_MINUTE;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_DAY_TO_SECOND: /* 'SQL_INTERVAL_DAY_TO_SECOND' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_DAY_TO_SECOND;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_HOUR_TO_MINUTE: /* 'SQL_INTERVAL_HOUR_TO_MINUTE' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_HOUR_TO_MINUTE;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_HOUR_TO_SECOND: /* 'SQL_INTERVAL_HOUR_TO_SECOND' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_HOUR_TO_SECOND;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
case SQL_INTERVAL_MINUTE_TO_SECOND: /* 'SQL_INTERVAL_MINUTE_TO_SECOND' type */
sColData[i].DataValue.DataType = SQL_C_INTERVAL_MINUTE_TO_SECOND;
sData = &sColData[i].DataValue.Data.DataInterval;
break;
default: /* Unknown data type */
SUNDB_SQL_THROW( SUNDB_FINISH_LABEL );
break;
}
/*
* SQLBindCol binds application data buffers to columns in the result set.
*
* If the TargetType argument is an interval data type,
* the default interval leading precision (2) and the default interval seconds precision (6),
* as set in the SQL_DESC_DATETIME_INTERVAL_PRECISION and SQL_DESC_PRECISION fields of the ARD,
* respectively, are used for the data.
*
* If the TargetType argument is SQL_C_NUMERIC, the default precision (driver-defined) and default scale (0),
* as set in the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the ARD, are used for the data.
*
* If any default precision or scale is not appropriate,
* the application should explicitly set the appropriate descriptor field by a call to SQLSetDescField or SQLSetDescRec.
*/
SUNDB_SQL_TRY( SQLBindCol( sStmt,
i,
sColData[i].DataValue.DataType,
sData,
sColData[i].ColInformation.ColOctetLength,
&sColData[i].DataValue.DataInd ) );
switch( sColData[i].DataValue.DataType )
{
case SQL_C_NUMERIC :
/*
* Set the datatype, precision and scale fields of the descriptor for the numeric column.
* Otherwise the default precision (driver defined) and scale (0) are returned.
*/
SUNDB_SQL_TRY( SQLSetDescField( sARD,
i,
SQL_DESC_PRECISION,
(SQLPOINTER)sColData[i].ColInformation.ColSize,
0 ) );
SUNDB_SQL_TRY( SQLSetDescField( sARD,
i,
SQL_DESC_SCALE,
(SQLPOINTER)(long)sColData[i].ColInformation.ColDecimalDigits,
0 ) );
break;
case SQL_INTERVAL_YEAR:
case SQL_INTERVAL_MONTH:
case SQL_INTERVAL_DAY:
case SQL_INTERVAL_HOUR:
case SQL_INTERVAL_MINUTE:
case SQL_INTERVAL_SECOND:
case SQL_INTERVAL_YEAR_TO_MONTH:
case SQL_INTERVAL_DAY_TO_HOUR:
case SQL_INTERVAL_DAY_TO_MINUTE:
case SQL_INTERVAL_DAY_TO_SECOND:
case SQL_INTERVAL_HOUR_TO_MINUTE:
case SQL_INTERVAL_HOUR_TO_SECOND:
case SQL_INTERVAL_MINUTE_TO_SECOND:
SUNDB_SQL_TRY( SQLGetDescField( sIRD,
i,
SQL_DESC_DATETIME_INTERVAL_PRECISION,
(void*)&sColData[i].ColInformation.ColLeadingPrecision,
SQL_IS_INTEGER,
0 ) );
SUNDB_SQL_TRY( SQLSetDescField( sARD,
i,
SQL_DESC_DATETIME_INTERVAL_PRECISION,
(void*)sColData[i].ColInformation.ColLeadingPrecision,
0 ) );
case SQL_TYPE_TIME:
case SQL_TYPE_TIME_WITH_TIMEZONE:
case SQL_TYPE_TIMESTAMP:
case SQL_TYPE_TIMESTAMP_WITH_TIMEZONE:
SUNDB_SQL_TRY( SQLSetDescField( sARD,
i,
SQL_DESC_PRECISION,
(void*)sColData[i].ColInformation.ColDecimalDigits,
0 ) );
default:
break;
}
}
/* Column names will be printed. */
printf( "\n" );
for( i = 1; i <= sColCount; i ++ )
{
printf( "%-15s ", sColData[i].ColInformation.ColName );
}
printf( "\n" );
for( i = 1; i <= sColCount; i ++ )
{
printf( "--------------- " );
}
printf( "\n" );
/* Data will be printed. */
while( 1 )
{
sReturn = SQLFetch( sStmt );
if( sReturn == SQL_NO_DATA )
{
break;
}
SUNDB_SQL_TRY( sReturn );
for( i = 1; i <= sColCount; i ++ )
{
/* The output format depends on the type of data. */
switch( sColData[i].DataValue.DataType )
{
case SQL_C_CHAR:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%-15s ", sColData[i].DataValue.Data.DataChar );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_SHORT:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%15d ", sColData[i].DataValue.Data.DataSmallInt );
}
else
{
printf( "%15s ", "(null)" );
}
break;
case SQL_C_LONG:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%15d ", sColData[i].DataValue.Data.DataInteger );
}
else
{
printf( "%15s ", "(null)" );
}
break;
case SQL_C_SBIGINT:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%15ld ", sColData[i].DataValue.Data.DataBigInt );
}
else
{
printf( "%15s ", "(null)" );
}
break;
case SQL_C_NUMERIC:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
/*
* Call to convert the little endian mode data into numeric data.
*/
sNumericValue = strtohextoval( &sColData[i].DataValue.Data.DataNumeric );
/*
* The returned value in the above code is scaled to the value specified
* in the scale field of the numeric structure. For example 25.212 would
* be returned as 25212. The scale in this case is 3 hence the integer
* value needs to be divided by 1000.
*/
sDivisor = 1;
if( sColData[i].DataValue.Data.DataNumeric.scale > 0 )
{
for( j = 0; j < sColData[i].DataValue.Data.DataNumeric.scale; j++ )
{
sDivisor = sDivisor * 10;
}
sFinalValue = (float)sNumericValue / (float)sDivisor;
}
else
{
for( j = sColData[i].DataValue.Data.DataNumeric.scale; j < 0; j++ )
{
sDivisor = sDivisor * 10;
}
sFinalValue = (float)sNumericValue * (float)sDivisor;
}
/*
* Examine the sign value returned in the sign field for the numeric structure.
* NOTE: The ODBC 3.0 spec required drivers to return the sign as
* 1 for positive numbers and 2 for negative number. This was changed in the
* ODBC 3.5 spec to return 0 for negative instead of 2.
*/
if( sColData[i].DataValue.Data.DataNumeric.sign == 0 )
{
sSign = -1;
}
else
{
sSign = 1;
}
sFinalValue *= sSign;
printf( "%15.3f ", sFinalValue );
}
else
{
printf( "%15s ", "(null)" );
}
break;
case SQL_C_FLOAT:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%15.3f ", sColData[i].DataValue.Data.DataReal );
}
else
{
printf( "%15s ", "(null)" );
}
break;
case SQL_C_DOUBLE:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%15.3f ", sColData[i].DataValue.Data.DataDouble );
}
else
{
printf( "%15s ", "(null)" );
}
break;
case SQL_C_BOOLEAN:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
printf( "%-15s ",
sColData[i].DataValue.Data.DataBoolean ? "true" : "false" );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_TYPE_DATE:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%-4d-%02d-%02d",
sColData[i].DataValue.Data.DataDate.year,
sColData[i].DataValue.Data.DataDate.month,
sColData[i].DataValue.Data.DataDate.day );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_TYPE_TIME:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%02d:%02d:%02d",
sColData[i].DataValue.Data.DataTime.hour,
sColData[i].DataValue.Data.DataTime.minute,
sColData[i].DataValue.Data.DataTime.second );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_TYPE_TIME_WITH_TIMEZONE:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%02u:%02u:%02u.%u +%02d:%02d",
sColData[i].DataValue.Data.DataTimeTZ.hour,
sColData[i].DataValue.Data.DataTimeTZ.minute,
sColData[i].DataValue.Data.DataTimeTZ.second,
sColData[i].DataValue.Data.DataTimeTZ.fraction,
sColData[i].DataValue.Data.DataTimeTZ.timezone_hour,
sColData[i].DataValue.Data.DataTimeTZ.timezone_minute );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_TYPE_TIMESTAMP:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%d-%02d-%02d %02d:%02d:%02d.%u",
sColData[i].DataValue.Data.DataTimeStamp.year,
sColData[i].DataValue.Data.DataTimeStamp.month,
sColData[i].DataValue.Data.DataTimeStamp.day,
sColData[i].DataValue.Data.DataTimeStamp.hour,
sColData[i].DataValue.Data.DataTimeStamp.minute,
sColData[i].DataValue.Data.DataTimeStamp.second,
sColData[i].DataValue.Data.DataTimeStamp.fraction );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_TYPE_TIMESTAMP_WITH_TIMEZONE:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%u-%02u-%02u %02u:%02u:%02u.%u +%02d:%02d",
sColData[i].DataValue.Data.DataTimeStampTZ.year,
sColData[i].DataValue.Data.DataTimeStampTZ.month,
sColData[i].DataValue.Data.DataTimeStampTZ.day,
sColData[i].DataValue.Data.DataTimeStampTZ.hour,
sColData[i].DataValue.Data.DataTimeStampTZ.minute,
sColData[i].DataValue.Data.DataTimeStampTZ.second,
sColData[i].DataValue.Data.DataTimeStampTZ.fraction,
sColData[i].DataValue.Data.DataTimeStampTZ.timezone_hour,
sColData[i].DataValue.Data.DataTimeStampTZ.timezone_minute );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_INTERVAL_YEAR:
/* FALL_THROUGH */ /* 'Interval_year_month' series use the same format */
case SQL_C_INTERVAL_MONTH:
/* FALL_THROUGH */ /* 'Interval_year_month' series use the same format */
case SQL_C_INTERVAL_YEAR_TO_MONTH:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%d-%02d",
sColData[i].DataValue.Data.DataInterval.intval.year_month.year,
sColData[i].DataValue.Data.DataInterval.intval.year_month.month );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
case SQL_C_INTERVAL_DAY:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_HOUR:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_MINUTE:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_SECOND:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_DAY_TO_HOUR:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_DAY_TO_MINUTE:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_DAY_TO_SECOND:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_HOUR_TO_MINUTE:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_HOUR_TO_SECOND:
/* FALL_THROUGH */ /* 'Interval_day_second' series use the same format */
case SQL_C_INTERVAL_MINUTE_TO_SECOND:
/* check null data */
if( sColData[i].DataValue.DataInd != SQL_NULL_DATA )
{
(void)snprintf( (char*)sDataBuffer,
BUF_LEN,
"%d %02d:%02d:%02d",
sColData[i].DataValue.Data.DataInterval.intval.day_second.day,
sColData[i].DataValue.Data.DataInterval.intval.day_second.hour,
sColData[i].DataValue.Data.DataInterval.intval.day_second.minute,
sColData[i].DataValue.Data.DataInterval.intval.day_second.second );
printf( "%-15s ", sDataBuffer );
}
else
{
printf( "%-15s ", "(null)" );
}
break;
default : /* Unknown data type */
printf( "Unknown data type : %d\n", sColData[i].DataValue.DataType );
SUNDB_SQL_THROW( SUNDB_FINISH_LABEL );
break;
}
if( i == sColCount )
{
printf( "\n");
}
}
/* SQLFetch () is the result of 'SQL_SUCCESS_WITH_INFO', then the error message is output. */
if( sReturn == SQL_SUCCESS_WITH_INFO )
{
PrintDiagnosticRecord( SQL_HANDLE_STMT, sStmt );
}
sCount ++;
}
printf( "\n%ld rows selected.\n\n", sCount );
/* SQLFreeHandleStmt frees resources associated with a connection */
sState = 0;
SUNDB_SQL_TRY( SQLFreeHandle( SQL_HANDLE_STMT, sStmt ) );
sStmt = NULL;
return SQL_SUCCESS;
SUNDB_FINISH;
switch(sState)
{
case 1:
PrintDiagnosticRecord( SQL_HANDLE_STMT, sStmt );
(void)SQLFreeHandle( SQL_HANDLE_STMT, sStmt );
sStmt = NULL;
default:
break;
}
return SQL_ERROR;
}
// int thread_proc(int argc, char **argv)
int thread_proc(void* ptr)
{
argv_t* arg;
arg = (argv_t*) ptr;
printf("[%s] start\n", arg->name);
int conn_type = 0;
if (arg->argc != 1)
{
printf("argc count error\n");
return (0);
}
// connection type (0:DA, 1:TCP)
conn_type = arg->conn_type;
SQLHENV sEnv = NULL;
SQLHDBC sDbc = NULL;
SQLINTEGER sState = 0;
sEnv = gsEnv[arg->id];
sDbc = gsDbc[arg->id];
/* If you call SQLAllocEnv() that is included in sunDB ODBC*/
SUNDB_SQL_TRY( SQLAllocHandle( SQL_HANDLE_ENV,
NULL,
&sEnv ) );
sState = 1;
/* SQLSetEnvAttr is sets attributes that govern aspects of environments */
SUNDB_SQL_TRY( SQLSetEnvAttr( sEnv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3,
0 ) );
/* If you call SQLAllocDbc that is mapped in the Driver Manager to SQLConnect */
SUNDB_SQL_TRY( SQLAllocHandle( SQL_HANDLE_DBC,
sEnv,
&sDbc ) );
sState = 2;
/* SQLConnect establishes connections to a driver and a data source */
/*
SUNDB_SQL_TRY( SQLConnect( sDbc,
(SQLCHAR*)"SUNDB",
SQL_NTS,
(SQLCHAR*)"test",
SQL_NTS,
(SQLCHAR*)"test",
SQL_NTS) );
*/
if (conn_type == 0) {
SUNDB_SQL_TRY( SQLDriverConnect( sDbc,
NULL,
(SQLCHAR*)"PROTOCOL=DA;UID=TEST;PWD=test",
SQL_NTS,
NULL,
0,
NULL,
SQL_DRIVER_NOPROMPT) );
} else {
// HOST=127.0.0.1;PORT=22581;
SUNDB_SQL_TRY( SQLDriverConnect( sDbc,
NULL,
(SQLCHAR*)"PROTOCOL=TCP;HOST=192.168.0.13;PORT=32581;UID=TEST;PWD=test",
SQL_NTS,
NULL,
0,
NULL,
SQL_DRIVER_NOPROMPT) );
}
sState = 3;
/* If you SQL_SUCCESS that is Select funtion success */
SUNDB_SQL_TRY( testSelect( sDbc ) );
/* SQLDisconnect cloese the connection associated with a specific connection handle */
sState = 2;
SUNDB_SQL_TRY( SQLDisconnect( sDbc ) );
/* SQLFreeHandleDbc frees resources associated with a connection */
sState = 1;
SUNDB_SQL_TRY( SQLFreeHandle( SQL_HANDLE_DBC,
sDbc ) );
sDbc = NULL;
/* SQLFreeHandleEnv frees resources associated with a environment */
sState = 0;
SUNDB_SQL_TRY( SQLFreeHandle( SQL_HANDLE_ENV,
sEnv ) );
sEnv = NULL;
printf("(SELECT_SUCCESS)\n");
printf("end:%s\n", arg->name);
arg->ret = arg->id;
pthread_exit(&arg->ret);
return EXIT_SUCCESS;
SUNDB_FINISH;
if( sDbc != NULL)
{
PrintDiagnosticRecord( SQL_HANDLE_DBC, sDbc );
}
if( sEnv != NULL)
{
PrintDiagnosticRecord( SQL_HANDLE_ENV, sEnv );
}
switch( sState )
{
case 3:
/* SQLDisconnect cloese the connection associated with a specific connection handle */
(void)SQLDisconnect( sDbc );
case 2:
/* SQLFreeHandleDbc frees resources associated with a connection */
(void)SQLFreeHandle( SQL_HANDLE_DBC, sDbc );
sDbc = NULL;
case 1:
/* SQLFreeHandleEnv frees resources associated with a environment */
(void)SQLFreeHandle( SQL_HANDLE_ENV, sEnv );
sEnv = NULL;
default:
break;
}
printf("(SELECT_FAILURE)\n");
printf("end:%s\n", arg->name);
arg->ret = arg->id;
pthread_exit(&arg->ret);
return EXIT_FAILURE;
}
int main(int argc, char **argv)
{
int i = 0;
int thread_count = THREAD_CNT;
pthread_t pthread[THREAD_CNT];
argv_t args[THREAD_CNT];
int* pthread_ret[THREAD_CNT] = { 0x00, };
memset( &gsEnv, 0x00, sizeof(gsEnv));
memset( &gsDbc, 0x00, sizeof(gsDbc));
for (i = 0; i < thread_count; i++)
{
args[i].id = i;
sprintf(args[i].name, "thread-%02d", args[i].id);
args[i].argc = argc;
args[i].argv = argv;
// conn_type (0=DA, 1=TCP)
if (i == 0) {
args[i].conn_type = 0;
} else {
args[i].conn_type = 1;
}
}
for (i = 0; i < thread_count; i++)
{
pthread_create(&pthread[i], NULL, (void*) &thread_proc,
(void*) &args[i]);
}
for (i = 0; i < thread_count; i++)
{
pthread_join(pthread[i], (void**) &pthread_ret[i]);
}
printf("[%d] ========= free.\n", 111);
for (i = 0; i < thread_count; i++)
{
// printf("[%s] exit->[%d]\n", args[i].name, *pthread_ret[i]);
}
return 0;
}