int main(int argc, char **argv)
{
	SQLRETURN rc;
	HSTMT hstmt = SQL_NULL_HSTMT;
	char *param1, *param2;
	SQLLEN cbParam1, cbParam2;
	SQLLEN param1bytes, param2bytes;
	PTR paramid;
	SQLLEN str_ind_array[2];
	SQLUSMALLINT status_array[2];
	SQLULEN nprocessed = 0;
	int i;

	test_connect();

	rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
	if (!SQL_SUCCEEDED(rc))
	{
		print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
		exit(1);
	}

	/****
	 * Bind with data-at-execution params. (VARBINARY)
	 */

	/* Prepare a statement */
	rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id FROM byteatab WHERE t = ? OR t = ?", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt);

	/* prepare the parameter values */
	param1 = "bar";
	param1bytes = strlen(param1);
	cbParam1 = SQL_DATA_AT_EXEC;
	param2 = "foobar";
	param2bytes = strlen(param2);
	cbParam2 = SQL_DATA_AT_EXEC;

	/* bind them. */
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
						  SQL_C_BINARY,	/* value type */
						  SQL_VARBINARY, /* param type */
						  param1bytes,	/* column size */
						  0,			/* dec digits */
						  (void *) 1,	/* param value ptr. For a data-at-exec
										 * param, this is a "parameter id" */
						  0,			/* buffer len */
						  &cbParam1		/* StrLen_or_IndPtr */);
	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);

	rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT,
						  SQL_C_BINARY,	/* value type */
						  SQL_VARBINARY, /* param type */
						  param2bytes,	/* column size */
						  0,			/* dec digits */
						  (void *) 2,	/* param value ptr. For a data-at-exec
										 * param, this is a "parameter id" */
						  0,			/* buffer len */
						  &cbParam2		/* StrLen_or_IndPtr */);
	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);

	/* Execute */
	rc = SQLExecute(hstmt);
	if (rc != SQL_NEED_DATA)
		CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

	/* set parameters */
	paramid = 0;
	while ((rc = SQLParamData(hstmt, &paramid)) == SQL_NEED_DATA)
	{
	  if (paramid == (void *) 1)
	  {
		  rc = SQLPutData(hstmt, param1, param1bytes);
		  CHECK_STMT_RESULT(rc, "SQLPutData failed", hstmt);
	  }
	  else if (paramid == (void *) 2)
	  {
		  rc = SQLPutData(hstmt, param2, param2bytes);
		  CHECK_STMT_RESULT(rc, "SQLPutData failed", hstmt);
	  }
	  else
	  {
		  printf("unexpected parameter id returned by SQLParamData: %p\n", paramid);
		  exit(1);
	  }
	}
	CHECK_STMT_RESULT(rc, "SQLParamData failed", hstmt);

	/* Fetch result */
	print_result(hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);


	/****
	 * Array binding with data-at-execution params.
	 */

	/* prepare the parameter values */
	str_ind_array[0] = SQL_DATA_AT_EXEC;
	str_ind_array[1] = SQL_DATA_AT_EXEC;

	/* Prepare a statement */
	rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id FROM byteatab WHERE t = ?", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt);

	SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
	SQLSetStmtAttr(hstmt, SQL_ATTR_PARAM_STATUS_PTR, status_array, 0);
	SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &nprocessed, 0);
	SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) 2, 0);

	/* bind the array. */
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
						  SQL_C_BINARY,	/* value type */
						  SQL_VARBINARY, /* param type */
						  5,			/* column size */
						  0,			/* dec digits */
						  (void *) 1,	/* param value ptr. For a data-at-exec
										 * param, this is "parameter id" */
						  0,			/* buffer len */
						  str_ind_array	/* StrLen_or_IndPtr */);
	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);

	/* Execute */
	rc = SQLExecute(hstmt);
	if (rc != SQL_NEED_DATA)
		CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

	/* set parameters */
	paramid = 0;
	while ((rc = SQLParamData(hstmt, &paramid)) == SQL_NEED_DATA)
	{
		if (nprocessed == 1)
			rc = SQLPutData(hstmt, "foo", strlen("foo"));
		else if (nprocessed == 2)
			rc = SQLPutData(hstmt, "barf", strlen("barf"));
		else
		{
			printf("unexpected # of rows processed after SQL_NEED_DATA: %u\n", (unsigned int) nprocessed);
			exit(1);
		}
		CHECK_STMT_RESULT(rc, "SQLPutData failed", hstmt);
	}
	CHECK_STMT_RESULT(rc, "SQLParamData failed", hstmt);

	/* Fetch results */
	printf("Parameter	Status\n");
	for (i = 0; i < nprocessed; i++)
	{
		switch (status_array[i])
		{
			case SQL_PARAM_SUCCESS:
			case SQL_PARAM_SUCCESS_WITH_INFO:
				break;

			case SQL_PARAM_ERROR:
				printf("%d\tError\n", i);
				break;

			case SQL_PARAM_UNUSED:
				printf("%d\tUnused\n", i);
				break;

			case SQL_PARAM_DIAG_UNAVAILABLE:
				printf("%d\tDiag unavailable\n", i);
				break;
		}
	}

	printf ("Fetching result sets for array bound (%u results expected)\n",
			(unsigned int) nprocessed);
	for (i = 1; rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO; i++)
	{
		printf("%d: ", i);
		print_result(hstmt);

		rc = SQLMoreResults(hstmt);
	}
	if (rc != SQL_NO_DATA)
		CHECK_STMT_RESULT(rc, "SQLMoreResults failed", hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	/* Clean up */
	test_disconnect();

	return 0;
}
Beispiel #2
0
int main()
{
  SQLHENV env;
  SQLHDBC dbc;
  SQLHSTMT stmt;
  SQLRETURN ret;
  SQLCHAR outstr[1024];
  SQLSMALLINT outstrlen;
  
  // Aloocate an environment handle
  ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&env);
  checkrc(ret,__LINE__);
  
   //we need odbc3 support
   SQLSetEnvAttr(env,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0);
   
  //ALLOCATE A Connection handle
  ret = SQLAllocHandle(SQL_HANDLE_DBC,env,&dbc);
  checkrc(ret,__LINE__);
    
  // connect to the DSN mydsn
    ret = SQLConnect (dbc,
                   (SQLCHAR *) "test", (SQLSMALLINT) strlen ("test"),
                   (SQLCHAR *) "root",
                   (SQLSMALLINT) strlen ("root"),
                   (SQLCHAR *) "manager",
                   (SQLSMALLINT) strlen (""));

 if(SQL_SUCCEEDED(ret)) 
 {
     printf("\nConnected to the Data Source..\n");
     
     
  }
   else
   {
        printf("error in connection\n");
        
        ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc);
        checkrc(ret,__LINE__);

        ret = SQLFreeHandle(SQL_HANDLE_ENV,env);
        checkrc(ret,__LINE__); 
        return 1; 
    }

   
   //******************************************************************
   // TABLE CREATED
   ret = SQLAllocHandle(SQL_HANDLE_STMT,dbc,&stmt);
   checkrc(ret,__LINE__);
   
   SQLCHAR table[200]=
     "CREATE TABLE T1(F1 INT,F2 SMALLINT,F3 CHAR(30),F4 FLOAT,F5 FLOAT,F6 DATE,F7 TIME,F8 TIMESTAMP,F9 TINYINT,F10 BIGINT)";
   ret = SQLPrepare(stmt,table,SQL_NTS);
   checkrc(ret,__LINE__);
   ret = SQLExecute(stmt);
   checkrc(ret,__LINE__);
   printf("\nTABLE CREATED\n"); 
   //*****************************
   InsertTest(env,dbc,stmt);  
   DeleteTest(env,dbc,stmt);

   //****************************************************************      
    SQLCHAR drop[100]="DROP TABLE T1";
    ret = SQLPrepare(stmt,drop,SQL_NTS);
    checkrc(ret,__LINE__);
    ret = SQLExecute(stmt);
    if(ret!=SQL_SUCCESS && ret !=SQL_SUCCESS_WITH_INFO)
       printf("Statement failed\n");
    else
       printf("Table  'T1' dropped successfully\n");  

    ret = SQLFreeHandle(SQL_HANDLE_STMT,stmt);
   checkrc(ret,__LINE__);

   ret = SQLDisconnect(dbc);
   checkrc(ret,__LINE__);
   
   ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc);
   checkrc(ret,__LINE__);
   
   ret = SQLFreeHandle(SQL_HANDLE_ENV,env);
   checkrc(ret,__LINE__);
   return 0;
}         
Beispiel #3
0
void TypeInfo::fillTypeInfo(SQLHDBC pHDBC)
{
	_pHDBC = &pHDBC;

	if (_typeInfo.empty() && _pHDBC)
	{
		const static int stringSize = 512;
		TypeInfoVec().swap(_typeInfo);

		SQLRETURN rc;
		SQLHSTMT hstmt = SQL_NULL_HSTMT;

		rc = SQLAllocHandle(SQL_HANDLE_STMT, *_pHDBC, &hstmt);
		if (!SQL_SUCCEEDED(rc))
			throw StatementException(hstmt, "SQLGetData()");

		rc = SQLGetTypeInfo(hstmt, SQL_ALL_TYPES);
		if (SQL_SUCCEEDED(rc))
		{
			while (SQLFetch(hstmt) != SQL_NO_DATA_FOUND)
			{
				char typeName[stringSize] = { 0 };
				char literalPrefix[stringSize] = { 0 };
				char literalSuffix[stringSize] = { 0 };
				char createParams[stringSize] = { 0 };
				char localTypeName[stringSize] = { 0 };
				
				TypeInfoTup ti("TYPE_NAME", "",
					"DATA_TYPE", 0,
					"COLUMN_SIZE", 0,
					"LITERAL_PREFIX", "",
					"LITERAL_SUFFIX", "",
					"CREATE_PARAMS", "",
					"NULLABLE", 0,
					"CASE_SENSITIVE", 0,
					"SEARCHABLE", 0,
					"UNSIGNED_ATTRIBUTE", 0,
					"FIXED_PREC_SCALE", 0,
					"AUTO_UNIQUE_VALUE", 0,
					"LOCAL_TYPE_NAME", "",
					"MINIMUM_SCALE", 0,
					"MAXIMUM_SCALE", 0,
					"SQL_DATA_TYPE", 0,
					"SQL_DATETIME_SUB", 0,
					"NUM_PREC_RADIX", 0,
					"INTERVAL_PRECISION", 0);

				SQLLEN ind = 0;
				rc = SQLGetData(hstmt, 1, SQL_C_CHAR, typeName, sizeof(typeName), &ind);
				ti.set<0>(typeName);
				rc = SQLGetData(hstmt, 2, SQL_C_SSHORT, &ti.get<1>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 3, SQL_C_SLONG, &ti.get<2>(), sizeof(SQLINTEGER), &ind);
				rc = SQLGetData(hstmt, 4, SQL_C_CHAR, literalPrefix, sizeof(literalPrefix), &ind);
				ti.set<3>(literalPrefix);
				rc = SQLGetData(hstmt, 5, SQL_C_CHAR, literalSuffix, sizeof(literalSuffix), &ind);
				ti.set<4>(literalSuffix);
				rc = SQLGetData(hstmt, 6, SQL_C_CHAR, createParams, sizeof(createParams), &ind);
				ti.set<5>(createParams);
				rc = SQLGetData(hstmt, 7, SQL_C_SSHORT, &ti.get<6>(), sizeof(SQLSMALLINT), &ind); 
				rc = SQLGetData(hstmt, 8, SQL_C_SSHORT, &ti.get<7>(), sizeof(SQLSMALLINT), &ind); 
				rc = SQLGetData(hstmt, 9, SQL_C_SSHORT, &ti.get<8>(), sizeof(SQLSMALLINT), &ind); 
				rc = SQLGetData(hstmt, 10, SQL_C_SSHORT, &ti.get<9>(), sizeof(SQLSMALLINT), &ind); 
				rc = SQLGetData(hstmt, 11, SQL_C_SSHORT, &ti.get<10>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 12, SQL_C_SSHORT, &ti.get<11>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 13, SQL_C_CHAR, localTypeName, sizeof(localTypeName), &ind);
				ti.set<12>(localTypeName);
				rc = SQLGetData(hstmt, 14, SQL_C_SSHORT, &ti.get<13>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 15, SQL_C_SSHORT, &ti.get<14>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 16, SQL_C_SSHORT, &ti.get<15>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 17, SQL_C_SSHORT, &ti.get<16>(), sizeof(SQLSMALLINT), &ind);
				rc = SQLGetData(hstmt, 18, SQL_C_SLONG, &ti.get<17>(), sizeof(SQLINTEGER), &ind);
				rc = SQLGetData(hstmt, 19, SQL_C_SSHORT, &ti.get<18>(), sizeof(SQLSMALLINT), &ind);

				_typeInfo.push_back(ti);
			}
		}

		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	}
}
Beispiel #4
0
static SQLRETURN extract_sql_error_rec( EHEAD *head,
        SQLCHAR *sqlstate,
        SQLINTEGER rec_number,
        SQLINTEGER *native_error,
        SQLCHAR *message_text,
        SQLSMALLINT buffer_length,
        SQLSMALLINT *text_length )
{
    SQLRETURN ret;

    if ( sqlstate )
        strcpy((char*) sqlstate, "00000" );

    if ( rec_number <= head -> sql_diag_head.internal_count )
    {
        ERROR *ptr;
        SQLCHAR *as1 = NULL;

        ptr = head -> sql_diag_head.internal_list_head;
        while( rec_number > 1 )
        {
            ptr = ptr -> next;
            rec_number --;
        }

        as1 = (SQLCHAR*) unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head ));

        if ( sqlstate )
        {
            unicode_to_ansi_copy((char*) sqlstate, ptr -> sqlstate, SQL_NTS, __get_connection( head ));
        }
        if ( buffer_length < strlen((char*) as1 ) + 1 )
        {
            ret = SQL_SUCCESS_WITH_INFO;
        }
        else
        {
            ret = SQL_SUCCESS;
        }

        if ( message_text && as1 )
        {
            if ( ret == SQL_SUCCESS )
            {
                strcpy((char*) message_text, (char*) as1 );
            }
            else
            {
                memcpy( message_text, as1, buffer_length );
                message_text[ buffer_length - 1 ] = '\0';
            }
        }

        if ( text_length && as1 )
        {
            *text_length = strlen((char*) as1 );
        }

        if ( native_error )
        {
            *native_error = ptr -> native_error;
        }

        /*
         * map 3 to 2 if required
         */

        if ( SQL_SUCCEEDED( ret ) && sqlstate )
            __map_error_state( (char*) sqlstate, __get_version( head ));

        if ( as1 )
        {
            free( as1 );
        }
        return ret;
    }
    else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 )
    {
        ERROR *ptr;
        SQLCHAR *as1 = NULL;
        SQLWCHAR *s1 = NULL, *s2 = NULL;

    	if ( rec_number <= head -> sql_diag_head.internal_count + 
            head -> sql_diag_head.error_count )
		{
        	rec_number -= head -> sql_diag_head.internal_count;
		}
		else
		{
        	rec_number -= ( head -> sql_diag_head.internal_count + head -> sql_diag_head.error_count );
		}

        s1 = malloc( sizeof( SQLWCHAR ) * ( 6 + 1 ));

        if ( buffer_length > 0 )
        {
            s2 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ));
        }

        if ( __get_connection( head ) -> unicode_driver &&
            CHECK_SQLGETDIAGRECW( __get_connection( head )))
        {
            ret = SQLGETDIAGRECW( __get_connection( head ),
                    head -> handle_type,
                    __get_driver_handle( head ),
                    rec_number,
                    s1,
                    native_error,
                    s2,
                    buffer_length,
                    text_length );

            /*
             * map 3 to 2 if required
             */

            if ( SQL_SUCCEEDED( ret ) && sqlstate )
            {
                if ( sqlstate )
                {
                    unicode_to_ansi_copy((char*) sqlstate, s1, SQL_NTS, __get_connection( head ));
                    __map_error_state((char*) sqlstate, __get_version( head ));
                }
                if ( message_text )
                {
                    unicode_to_ansi_copy((char*) message_text, s2, SQL_NTS, __get_connection( head ));
                }
            }

        }
        else if ( !__get_connection( head ) -> unicode_driver &&
            CHECK_SQLGETDIAGREC( __get_connection( head )))
        {
            ret = SQLGETDIAGREC( __get_connection( head ),
                    head -> handle_type,
                    __get_driver_handle( head ),
                    rec_number,
                    sqlstate,
                    native_error,
                    message_text,
                    buffer_length,
                    text_length );

            /*
             * map 3 to 2 if required
             */

            if ( SQL_SUCCEEDED( ret ) && sqlstate )
                __map_error_state((char*) sqlstate, __get_version( head ));
        }
        else
        {
            SQLCHAR *as1 = NULL;

            ptr = head -> sql_diag_head.error_list_head;
            while( rec_number > 1 )
            {
                ptr = ptr -> next;
                rec_number --;
            }

            as1 = (SQLCHAR*) unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head ));

            if ( sqlstate )
            {
                unicode_to_ansi_copy((char*) sqlstate, ptr -> sqlstate, SQL_NTS, __get_connection( head ));
            }
            if ( as1 && buffer_length < strlen((char*) as1 ) + 1 )
            {
                ret = SQL_SUCCESS_WITH_INFO;
            }
            else
            {
                ret = SQL_SUCCESS;
            }

            if ( message_text && as1 )
            {
                if ( ret == SQL_SUCCESS )
                {
                    strcpy((char*) message_text,(char*) as1 );
                }
                else
                {
                    memcpy( message_text, as1, buffer_length );
                    message_text[ buffer_length - 1 ] = '\0';
                }
            }

            if ( text_length && as1 )
            {
                *text_length = strlen((char*) as1 );
            }

            if ( native_error )
            {
                *native_error = ptr -> native_error;
            }

            /*
             * map 3 to 2 if required
             */

            if ( SQL_SUCCEEDED( ret ) && sqlstate )
                __map_error_state((char*) sqlstate, __get_version( head ));

            if ( as1 )
            {
                free( as1 );
            }
        }

        if ( s1 )
            free( s1 );

        if ( s2 )
            free( s2 );

        return ret;
    }
    else 
    {
	    return SQL_NO_DATA;
    }
}
Beispiel #5
0
int main(int argc, char **argv)
{
	SQLRETURN rc;
	HSTMT hstmt = SQL_NULL_HSTMT;
	char param1[20] = { 1, 2, 3, 4, 5, 6, 7, 8 };
	SQLLEN cbParam1;
	SQLSMALLINT colcount;
	SQLSMALLINT dataType;
	SQLULEN paramSize;
	SQLSMALLINT decDigits;
	SQLSMALLINT nullable;

	test_connect();

	rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
	if (!SQL_SUCCEEDED(rc))
	{
		print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
		exit(1);
	}

	/**** Query with a bytea param ****/

	/* Prepare a statement */
	rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id, t FROM byteatab WHERE t = ?", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt);

	/* bind param  */
	cbParam1 = 8;
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
						  SQL_C_BINARY,	/* value type */
						  SQL_BINARY,	/* param type */
						  20,			/* column size */
						  0,			/* dec digits */
						  param1,		/* param value ptr */
						  0,			/* buffer len */
						  &cbParam1		/* StrLen_or_IndPtr */);
	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);

	/* Test SQLNumResultCols, called before SQLExecute() */
	rc = SQLNumResultCols(hstmt, &colcount);
	CHECK_STMT_RESULT(rc, "SQLNumResultCols failed", hstmt);
	printf("# of result cols: %d\n", colcount);

	/* Execute */
	rc = SQLExecute(hstmt);
	CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

	/* Fetch result */
	print_result(hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	/*** Test SQLBindParameter with SQLExecDirect ***/
	printf("\nTesting SQLBindParameter with SQLExecDirect...\n");

	/* bind param  */
	strcpy(param1, "bar");
	cbParam1 = SQL_NTS;
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
						  SQL_C_CHAR,	/* value type */
						  SQL_CHAR,		/* param type */
						  20,			/* column size */
						  0,			/* dec digits */
						  param1,		/* param value ptr */
						  0,			/* buffer len */
						  &cbParam1		/* StrLen_or_IndPtr */);
	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);

	rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT 'foo' UNION ALL SELECT ?", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);
	print_result(hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	/*** Test SQLDescribeParam ***/
	printf("\nTesting SQLDescribeParam...\n");

	rc = SQLFreeStmt(hstmt, SQL_RESET_PARAMS);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	/* Prepare a statement */
	rc = SQLPrepare(hstmt, (SQLCHAR *) "SELECT id, t FROM testtab1 WHERE id = ?", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLPrepare failed", hstmt);

	rc = SQLDescribeParam(hstmt, 1, &dataType, &paramSize, &decDigits, &nullable);
	CHECK_STMT_RESULT(rc, "SQLDescribeParams failed", hstmt);
	printf("Param 1: type %s; size %u; dec digits %d; %s\n",
		   datatype_str(dataType), (unsigned int) paramSize, decDigits, nullable_str(nullable));
	/* bind param  */
	strcpy(param1, "3");
	cbParam1 = SQL_NTS;
	rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT,
						  SQL_C_CHAR,	/* value type */
						  SQL_CHAR,		/* param type */
						  20,			/* column size */
						  0,			/* dec digits */
						  param1,		/* param value ptr */
						  0,			/* buffer len */
						  &cbParam1		/* StrLen_or_IndPtr */);
	CHECK_STMT_RESULT(rc, "SQLBindParameter failed", hstmt);

	/* Test SQLNumResultCols, called before SQLExecute() */
	rc = SQLNumResultCols(hstmt, &colcount);
	CHECK_STMT_RESULT(rc, "SQLNumResultCols failed", hstmt);
	printf("# of result cols: %d\n", colcount);

	/* Execute */
	rc = SQLExecute(hstmt);
	CHECK_STMT_RESULT(rc, "SQLExecute failed", hstmt);

	/* Fetch result */
	print_result(hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	/* Clean up */
	test_disconnect();

	return 0;
}
bool OdbcConnection::Connect()
{
	if (m_szDSN.empty())
		return false;

	FastGuard lock(m_lock);

	tstring szConn = _T("DSN=") + m_szDSN + _T(";");
	// Reconnect if we need to.
	if (isConnected())
		Disconnect();

	// Allocate enviroment handle
	if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &m_envHandle)))
	{
		ReportSQLError(SQL_HANDLE_ENV, m_envHandle, _T("SQLAllocHandle"), _T("Unable to allocate environment handle."));
		goto error_handler;
	}

	// Request ODBC3 support
	if (!SQL_SUCCEEDED(SQLSetEnvAttr(m_envHandle, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0)))
	{
		ReportSQLError(SQL_HANDLE_ENV, m_envHandle, _T("SQLSetEnvAttr"), _T("Unable to set environment attribute (SQL_ATTR_ODBC_VERSION)."));
		goto error_handler;
	}

	// Allocate the connection handle
	if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_DBC, m_envHandle, &m_connHandle)))
	{
		ReportSQLError(SQL_HANDLE_ENV, m_envHandle, _T("SQLAllocHandle"), _T("Unable to allocate connection handle."));
		goto error_handler;
	}

	if (m_szUser.length())
	{
		szConn += _T("UID=") + m_szUser + _T(";");
		if (m_szPass.length())
			szConn += _T("PWD=") + m_szPass + _T(";");
	}

	// Enable multiple active result sets
	if (m_bMarsEnabled)
	{
		if (!SQL_SUCCEEDED(SQLSetConnectAttr(m_connHandle, SQL_COPT_SS_MARS_ENABLED, SQL_MARS_ENABLED_YES, SQL_IS_UINTEGER)))
		{
			printf("** WARNING **\n\n");
			printf("Attempted to used MARS (Multiple Active Result Sets), but this\n");
			printf("feature is not supported by your ODBC driver or SQL Server version.\n\n");
			printf("To benefit from MARS, you need to be using at least SQL Server 2005, and at\n");
			printf("least the 'SQL Native Client' ODBC driver (as opposed to the vastly outdated\n'SQL Server' driver).\n\n");
			printf("Continuing to connect without MARS.\n\n");
			m_bMarsEnabled = false;
		}

		// NOTE: We can enable MARS via specifying the following, but we are unable to detect if it's supported this way.
		// szConn += _T("MARS_Connection=yes;");
	}

	if (!SQL_SUCCEEDED(SQLDriverConnect(m_connHandle, SQL_NULL_HANDLE, (SQLTCHAR *)szConn.c_str(), SQL_NTS, 0, 0, 0, 0)))
	{
		ReportSQLError(SQL_HANDLE_DBC, m_connHandle, _T("SQLDriverConnect"), _T("Unable to establish connection."));
		goto error_handler;
	}

	for (auto itr = m_commandSet.begin(); itr != m_commandSet.end(); itr++)
		(*itr)->SetConnectionHandle(m_connHandle);

	return true;

error_handler:
	ResetHandles();
	return false;
}
Beispiel #7
0
/*!
 * \brief Gets a partial result set, fetch rows from a result
 *
 * Gets a partial result set, fetch a number of rows from a databae result.
 * This function initialize the given result structure on the first run, and
 * fetches the nrows number of rows. On subsequenting runs, it uses the
 * existing result and fetches more rows, until it reaches the end of the
 * result set. Because of this the result needs to be null in the first
 * invocation of the function. If the number of wanted rows is zero, the
 * function returns anything with a result of zero.
 * \param _h structure representing the database connection
 * \param _r pointer to a structure representing the result
 * \param nrows number of fetched rows
 * \return return zero on success, negative value on failure
 */
int db_unixodbc_fetch_result(const db1_con_t* _h, db1_res_t** _r, const int nrows)
{
	int row_n = 0, i = 0, ret = 0, len;
	SQLSMALLINT columns;
	list* rows = NULL;
	list* rowstart = NULL;
	strn* temp_row = NULL;

	if ((!_h) || (!_r) || nrows < 0)
	{
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	/* exit if the fetch count is zero */
	if (nrows == 0) {
		if (*_r)
			db_free_result(*_r);
		*_r = 0;
		return 0;
	}

	/* On the first fetch for a query, allocate structures and get columns */
	if(*_r == NULL) {
		/* Allocate a new result structure */
		*_r = db_new_result();
		LM_DBG("just allocated a new db result structure");

		if (*_r == NULL) {
			LM_ERR("no memory left\n");
			return -2;
		}

		/* Get columns names and count */
		if (db_unixodbc_get_columns(_h, *_r) < 0) {
			LM_ERR("getting column names failed\n");
			db_free_columns(*_r);
			return -2;
		}

	/* On subsequent fetch attempts, reuse already allocated structures */
	} else {
		LM_DBG("db result structure already exist, reusing\n");
		/* free old rows */
		if(RES_ROWS(*_r) != NULL)
			db_free_rows(*_r);
		RES_ROWS(*_r) = 0;
		RES_ROW_N(*_r) = 0;
	}

	SQLNumResultCols(CON_RESULT(_h), (SQLSMALLINT *)&columns);

	/* Now fetch nrows at most */
	len = sizeof(db_row_t) * nrows;
	RES_ROWS(*_r) = (struct db_row*)pkg_malloc(len);
	if (!RES_ROWS(*_r)) {
		LM_ERR("no memory left\n");
		return -5;
	}
	LM_DBG("allocated %d bytes for RES_ROWS at %p\n", len, RES_ROWS(*_r));

	LM_DBG("Now fetching %i rows at most\n", nrows);
	while(SQL_SUCCEEDED(ret = SQLFetch(CON_RESULT(_h)))) {
		/* Allocate a temporary row */
		temp_row = db_unixodbc_new_cellrow(columns);
		if (!temp_row) {
			LM_ERR("no private memory left\n");
			pkg_free(RES_ROWS(*_r));
			pkg_free(*_r);
			*_r = 0;
			return -1;
		}

		LM_DBG("fetching %d columns for row %d...\n",columns, row_n);
		for(i=0; i < columns; i++) {
			LM_DBG("fetching column %d\n",i);
			if (!db_unixodbc_load_cell(_h, i+1, temp_row + i, RES_TYPES(*_r)[i])) {
			    pkg_free(RES_ROWS(*_r));
			    db_unixodbc_free_cellrow(columns, temp_row);
			    pkg_free(*_r);
			    *_r = 0;
			    return -5;
			}
		}

		LM_DBG("got temp_row at %p\n", temp_row);

		if (db_unixodbc_list_insert(&rowstart, &rows, columns, temp_row) < 0) {
			LM_ERR("SQL result row insert failed\n");
			pkg_free(RES_ROWS(*_r));
			db_unixodbc_free_cellrow(columns, temp_row);
			pkg_free(*_r);
			*_r = 0;
			return -5;
		}

		/* Free temporary row data */
		LM_DBG("freeing temp_row at %p\n", temp_row);
		db_unixodbc_free_cellrow(columns, temp_row);
		temp_row = NULL;

		row_n++;
		if (row_n == nrows) {
			break;
		}
	}

	CON_ROW(_h) = NULL;

	RES_ROW_N(*_r) = row_n;
	if (!row_n) {
		LM_DBG("no more rows to process for db fetch");
		pkg_free(RES_ROWS(*_r));
		RES_ROWS(*_r) = 0;
		return 0;
	}

	/* Convert rows to internal format */
	memset(RES_ROWS(*_r), 0, len);
	i = 0;
	rows = rowstart;
	while(rows)
	{
		LM_DBG("converting row #%d\n", i);
		CON_ROW(_h) = rows->data;
		if (!CON_ROW(_h))
		{
			LM_ERR("string null\n");
			RES_ROW_N(*_r) = row_n;
			db_free_rows(*_r);
			return -3;
		}
		if (db_unixodbc_convert_row(_h, *_r, &(RES_ROWS(*_r)[i]), rows->lengths) < 0) {
			LM_ERR("converting fetched row #%d failed\n", i);
			RES_ROW_N(*_r) = i;
			db_free_rows(*_r);
			return -4;
		}
		i++;
		rows = rows->next;
	}
	db_unixodbc_list_destroy(rowstart);

	/* update the total number of rows processed */
	RES_LAST_ROW(*_r) += row_n;
	LM_DBG("fetch from db processed %d rows so far\n", RES_LAST_ROW(*_r));

	return 0;
}
Beispiel #8
0
int FetchTest(SQLHANDLE env, SQLHANDLE dbc, SQLHANDLE stmt)
{
    int ret;

    SQLCHAR szSchema[STR_LEN];
    SQLCHAR szCatalog[STR_LEN];
    SQLCHAR szColumnName[STR_LEN];
    SQLCHAR szTableName[STR_LEN];
    SQLCHAR szTypeName[STR_LEN];
    SQLCHAR szRemarks[REM_LEN];
    SQLCHAR szColumnDefault[STR_LEN];
    SQLCHAR szIsNullable[STR_LEN];

    SQLINTEGER ColumnSize;
    SQLINTEGER BufferLength;
    SQLINTEGER CharOctetLength;
    SQLINTEGER OrdinalPosition;

    SQLSMALLINT DataType;
    SQLSMALLINT DecimalDigits;
    SQLSMALLINT NumPrecRadix;
    SQLSMALLINT Nullable;
    SQLSMALLINT SQLDataType;
    SQLSMALLINT DatetimeSubtypeCode;

    ret = SQLColumns(stmt, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"", SQL_NTS, (SQLCHAR*)"T1", SQL_NTS, NULL, 0);
    checkrc(ret,__LINE__);
    short totalFields = 0 ;
    ret = SQLNumResultCols (stmt, &totalFields);
    checkrc(ret,__LINE__);
    printf( "No of columns in resultset = %d\n",totalFields);


    SQLBindCol(stmt, 1, SQL_C_CHAR, szCatalog, STR_LEN,NULL);
    SQLBindCol(stmt, 2, SQL_C_CHAR, szSchema, STR_LEN, NULL);
    SQLBindCol(stmt, 3, SQL_C_CHAR, szTableName, STR_LEN,NULL);
    SQLBindCol(stmt, 4, SQL_C_CHAR, szColumnName, STR_LEN, NULL);
    SQLBindCol(stmt, 5, SQL_C_SSHORT, &DataType, 0, NULL);
    SQLBindCol(stmt, 6, SQL_C_CHAR, szTypeName, STR_LEN, NULL);
    SQLBindCol(stmt, 7, SQL_C_SLONG, &ColumnSize, 0, NULL);
    SQLBindCol(stmt, 8, SQL_C_SLONG, &BufferLength, 0, NULL);
    SQLBindCol(stmt, 9, SQL_C_SSHORT, &DecimalDigits, 0, NULL);
    SQLBindCol(stmt, 10, SQL_C_SSHORT, &NumPrecRadix, 0, NULL);
    SQLBindCol(stmt, 11, SQL_C_SSHORT, &Nullable, 0, NULL);
    SQLBindCol(stmt, 12, SQL_C_CHAR, szRemarks, REM_LEN, NULL);
    SQLBindCol(stmt, 13, SQL_C_CHAR, szColumnDefault, STR_LEN, NULL);
    SQLBindCol(stmt, 14, SQL_C_SSHORT, &SQLDataType, 0, NULL);
    SQLBindCol(stmt, 15, SQL_C_SSHORT, &DatetimeSubtypeCode, 0,NULL);
    SQLBindCol(stmt, 16, SQL_C_SLONG, &CharOctetLength, 0, NULL);
    SQLBindCol(stmt, 17, SQL_C_SLONG, &OrdinalPosition, 0, NULL);
    SQLBindCol(stmt, 18, SQL_C_CHAR, szIsNullable, STR_LEN, NULL);

    while(SQL_SUCCEEDED(ret = SQLFetch(stmt))) {
        printf("szCatalog =%s \t szSchema=%s \t szTableName=%s \t szColumnName= %s \t DataType = %d ColumnSize = %d  Nullable =%d szRemarks = %s, OrdinalPosition =%d szIsNullable =%s\n ",szCatalog,szSchema,szTableName,szColumnName,DataType,ColumnSize,Nullable,szRemarks,OrdinalPosition,szIsNullable);
    }
    ret = SQLCloseCursor(stmt);
    checkrc(ret,__LINE__);

    ret = SQLTransact(env,dbc,SQL_COMMIT);
    checkrc(ret,__LINE__);
    return 0;
}
SQLRETURN MADB_DaeStmt(MADB_Stmt *Stmt, SQLUSMALLINT Operation)
{
  char          *TableName=   MADB_GetTableName(Stmt);
  char          *CatalogName= MADB_GetCatalogName(Stmt);
  MADB_DynString DynStmt;

  MADB_CLEAR_ERROR(&Stmt->Error);
  memset(&DynStmt, 0, sizeof(MADB_DynString));

  if (Stmt->DaeStmt)
    Stmt->Methods->StmtFree(Stmt->DaeStmt, SQL_DROP);
  Stmt->DaeStmt= NULL;

  if (!SQL_SUCCEEDED(MA_SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE)Stmt->Connection, (SQLHANDLE *)&Stmt->DaeStmt)))
  {
    MADB_CopyError(&Stmt->Error, &Stmt->Connection->Error);
    goto end;
  }

  switch(Operation)
  {
  case SQL_ADD:
    if (MADB_InitDynamicString(&DynStmt, "INSERT INTO ", 1024, 1024) ||
        MADB_DynStrAppendQuoted(&DynStmt, CatalogName) ||
        MADB_DynstrAppend(&DynStmt, ".") ||
        MADB_DynStrAppendQuoted(&DynStmt, TableName)||
        MADB_DynStrUpdateSet(Stmt, &DynStmt))
    {
      MADB_DynstrFree(&DynStmt);
      return Stmt->Error.ReturnValue;
    }
    Stmt->DataExecutionType= MADB_DAE_ADD;
    break;
  case SQL_DELETE:
    if (MADB_InitDynamicString(&DynStmt, "DELETE FROM ", 1024, 1024) ||
        MADB_DynStrAppendQuoted(&DynStmt, CatalogName) ||
        MADB_DynstrAppend(&DynStmt, ".") ||
        MADB_DynStrAppendQuoted(&DynStmt, TableName) ||
        MADB_DynStrGetWhere(Stmt, &DynStmt, TableName, FALSE))
    {
      MADB_DynstrFree(&DynStmt);
      return Stmt->Error.ReturnValue;
    }
    Stmt->DataExecutionType= MADB_DAE_DELETE;
    break;
  case SQL_UPDATE:
    if (MADB_InitDynamicString(&DynStmt, "UPDATE ", 1024, 1024) ||
        MADB_DynStrAppendQuoted(&DynStmt, CatalogName) ||
        MADB_DynstrAppend(&DynStmt, ".") ||
        MADB_DynStrAppendQuoted(&DynStmt, TableName)||
        MADB_DynStrUpdateSet(Stmt, &DynStmt)||
        MADB_DynStrGetWhere(Stmt, &DynStmt, TableName, FALSE))
    {
      MADB_DynstrFree(&DynStmt);
      return Stmt->Error.ReturnValue;
    }
    Stmt->DataExecutionType= MADB_DAE_UPDATE;
    break;
  }
  
  if (!SQL_SUCCEEDED(Stmt->DaeStmt->Methods->Prepare(Stmt->DaeStmt, (SQLCHAR *)DynStmt.str, SQL_NTS, FALSE)))
  {
    MADB_CopyError(&Stmt->Error, &Stmt->DaeStmt->Error);
    Stmt->Methods->StmtFree(Stmt->DaeStmt, SQL_DROP);
  }
   
end:
  MADB_DynstrFree(&DynStmt);
  return Stmt->Error.ReturnValue;

}
Beispiel #10
0
SQLRETURN SQL_API
SQLGetConnectAttrW(SQLHDBC ConnectionHandle,
		   SQLINTEGER Attribute,
		   SQLPOINTER ValuePtr,
		   SQLINTEGER BufferLength,
		   SQLINTEGER *StringLengthPtr)
{
	ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
	SQLRETURN rc;
	SQLPOINTER ptr;
	SQLINTEGER n;

#ifdef ODBCDEBUG
	ODBCLOG("SQLGetConnectAttrW " PTRFMT " %s " PTRFMT " %d " PTRFMT "\n",
		PTRFMTCAST ConnectionHandle,
		translateConnectAttribute(Attribute),
		PTRFMTCAST ValuePtr, (int) BufferLength,
		PTRFMTCAST StringLengthPtr);
#endif

	if (!isValidDbc(dbc))
		return SQL_INVALID_HANDLE;

	clearDbcErrors(dbc);

	switch (Attribute) {
	/* all string attributes */
	case SQL_ATTR_CURRENT_CATALOG:
		ptr = malloc(BufferLength);
		if (ptr == NULL) {
			/* Memory allocation error */
			addDbcError(dbc, "HY001", NULL, 0);
			return SQL_ERROR;
		}
		break;
	default:
		ptr = ValuePtr;
		break;
	}

	rc = MNDBGetConnectAttr(dbc, Attribute, ptr, BufferLength, &n);

	if (ptr != ValuePtr) {
		if (rc == SQL_SUCCESS_WITH_INFO) {
			clearDbcErrors(dbc);
			free(ptr);
			ptr = malloc(++n); /* add one for NULL byte */
			if (ptr == NULL) {
				/* Memory allocation error */
				addDbcError(dbc, "HY001", NULL, 0);
				return SQL_ERROR;
			}
			rc = MNDBGetConnectAttr(dbc, Attribute, ptr, n, &n);
		}
		if (SQL_SUCCEEDED(rc)) {
			SQLSMALLINT nn = (SQLSMALLINT) n;

			fixWcharOut(rc, ptr, nn, ValuePtr, BufferLength,
				    StringLengthPtr, 2, addDbcError, dbc);
		}
		free(ptr);
	} else if (StringLengthPtr)
		*StringLengthPtr = n;

	return rc;
}
Beispiel #11
0
static PyObject* CnxnInfo_New(Connection* cnxn)
{
    CnxnInfo* p = PyObject_NEW(CnxnInfo, &CnxnInfoType);
    if (!p)
        return 0;
    Object info((PyObject*)p);

    // set defaults
    p->odbc_major             = 3;
    p->odbc_minor             = 50;
    p->supports_describeparam = false;
    p->datetime_precision     = 19; // default: "yyyy-mm-dd hh:mm:ss"

    // WARNING: The GIL lock is released for the *entire* function here.  Do not touch any objects, call Python APIs,
    // etc.  We are simply making ODBC calls and setting atomic values (ints & chars).  Also, make sure the lock gets
    // released -- do not add an early exit.

    SQLRETURN ret;
    Py_BEGIN_ALLOW_THREADS

    char szVer[20];
    SQLSMALLINT cch = 0;
    ret = SQLGetInfo(cnxn->hdbc, SQL_DRIVER_ODBC_VER, szVer, _countof(szVer), &cch);
    if (SQL_SUCCEEDED(ret))
    {
        char* dot = strchr(szVer, '.');
        if (dot)
        {
            *dot = '\0';
            p->odbc_major=(char)atoi(szVer);
            p->odbc_minor=(char)atoi(dot + 1);
        }
    }

    char szYN[2];
    ret = SQLGetInfo(cnxn->hdbc, SQL_DESCRIBE_PARAMETER, szYN, _countof(szYN), &cch);
    if (SQL_SUCCEEDED(ret))
    {
        p->supports_describeparam = szYN[0] == 'Y';
    }

    // What is the datetime precision?  This unfortunately requires a cursor (HSTMT).

    HSTMT hstmt = 0;
    if (SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, cnxn->hdbc, &hstmt)))
    {
        if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_TYPE_TIMESTAMP)) && SQL_SUCCEEDED(SQLFetch(hstmt)))
        {
            SQLINTEGER columnsize;
            if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0)))
            {
                p->datetime_precision = columnsize;
            }
        }

        SQLFreeStmt(hstmt, SQL_CLOSE);
    }

    Py_END_ALLOW_THREADS

    // WARNING: Released the lock now.
    
    return info.Detach();
}
Beispiel #12
0
SQLRETURN __SQLFreeHandle( SQLSMALLINT handle_type,
        SQLHANDLE handle )
{
    switch( handle_type )
    {
      case SQL_HANDLE_ENV:
        {
            DMHENV environment = (DMHENV)handle;

            /*
             * check environment
             */

            if ( !__validate_env( environment ))
            {
                dm_log_write( __FILE__, 
                        __LINE__, 
                        LOG_INFO, 
                        LOG_INFO, 
                        "Error: SQL_INVALID_HANDLE" );

                return SQL_INVALID_HANDLE;
            }
            
            function_entry( environment );

            if ( log_info.log_flag )
            {
                sprintf( environment -> msg,
                        "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p",
                        handle_type,
                        (void*)handle );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        environment -> msg );
            }

            thread_protect( SQL_HANDLE_ENV, environment );

            /*
             * check states
             */
            if ( environment -> state != STATE_E1 )
            {
                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        "Error: HY010" );

                __post_internal_error( &environment -> error,
                        ERROR_HY010, NULL,
                        environment -> requested_version );

                return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR );
            }

            thread_release( SQL_HANDLE_ENV, environment );

            __release_env( environment );
            return SQL_SUCCESS;
        }
        break;

      case SQL_HANDLE_DBC:
        {
            DMHDBC connection = (DMHDBC)handle;
            DMHENV environment;

            /*
             * check connection
             */

            if ( !__validate_dbc( connection ))
            {
                dm_log_write( __FILE__, 
                            __LINE__, 
                            LOG_INFO, 
                            LOG_INFO, 
                            "Error: SQL_INVALID_HANDLE" );

                return SQL_INVALID_HANDLE;
            }

            function_entry( connection );

            environment = connection -> environment;

            if ( log_info.log_flag )
            {
                sprintf( connection -> msg,
                        "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p",
                        handle_type,
                        (void*)handle );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        connection -> msg );
            }

            thread_protect( SQL_HANDLE_ENV, environment );

            /*
             * check states
             */
            if ( connection -> state != STATE_C2 )
            {
                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        "Error: HY010" );

                __post_internal_error( &connection -> error,
                        ERROR_HY010, NULL,
                        connection -> environment -> requested_version );

                return function_return( SQL_HANDLE_ENV, environment, SQL_ERROR );
            }

            environment -> connection_count --;

            if ( environment -> connection_count == 0 )
            {
                environment -> state = STATE_E1;
            }

            environment = connection -> environment;

            __release_attr_str( &connection -> env_attribute );
            __release_attr_str( &connection -> dbc_attribute );
            __release_attr_str( &connection -> stmt_attribute );

            __disconnect_part_one( connection );

            __release_dbc( connection );

            if ( log_info.log_flag )
            {
                sprintf( environment -> msg,
                        "\n\t\tExit:[SQL_SUCCESS]" );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        environment -> msg );
            }
#if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H )
            uodbc_update_stats(environment->sh, UODBC_STATS_TYPE_HDBC,
                               (void *)-1);
#endif

            thread_release( SQL_HANDLE_ENV, environment );

            return SQL_SUCCESS;
        }
        break;

      case SQL_HANDLE_STMT:
        {
            DMHSTMT statement = (DMHSTMT)handle;
            DMHDBC connection;
            SQLRETURN ret;

            /*
             * check statement
             */
            if ( !__validate_stmt( statement ))
            {
                dm_log_write( __FILE__, 
                            __LINE__, 
                            LOG_INFO, 
                            LOG_INFO, 
                            "Error: SQL_INVALID_HANDLE" );

                return SQL_INVALID_HANDLE;
            }

            function_entry( statement );

            connection = statement -> connection;

            if ( log_info.log_flag )
            {
                sprintf( statement -> msg,
                        "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p",
                        handle_type,
                        (void*)handle );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        statement -> msg );
            }

            thread_protect( SQL_HANDLE_STMT, statement );

            /*
             * check states
             */
            if ( statement -> state == STATE_S8 ||
                    statement -> state == STATE_S9 ||
                    statement -> state == STATE_S10 ||
                    statement -> state == STATE_S11 ||
                    statement -> state == STATE_S12 )
            {
                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        "Error: HY010" );

                __post_internal_error( &statement -> error,
                          ERROR_HY010, NULL,
                          statement -> connection -> environment -> requested_version );

                return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
            }

            if ( !CHECK_SQLFREEHANDLE( statement -> connection ))
            {
                if ( !CHECK_SQLFREESTMT( statement -> connection ))
                {
                    dm_log_write( __FILE__,
                            __LINE__,
                            LOG_INFO,
                            LOG_INFO,
                            "Error: IM001" );

                    __post_internal_error( &statement -> error,
                            ERROR_IM001, NULL,
                            statement -> connection -> environment -> requested_version );

                    return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
                }
                else
                {
                    ret = SQLFREESTMT( statement -> connection,
                        statement -> driver_stmt,
                        SQL_DROP );
                }
            }
            else
            {
                ret = SQLFREEHANDLE( statement -> connection,
                        handle_type,
                        statement -> driver_stmt );
            }

            if ( SQL_SUCCEEDED( ret ))
            {
                /*
                 * break any association
                 */

                if ( statement -> ard ) {
                    statement -> ard -> associated_with = NULL;
                }
                if ( statement -> apd ) {
                    statement -> apd -> associated_with = NULL;
                }
                /*
                 * release the implicit descriptors, 
				 * this matches the tests in SQLAllocHandle
                 */
                if (( statement -> connection -> driver_act_ver == 3 &&
						CHECK_SQLGETSTMTATTR( connection )) ||
						CHECK_SQLGETSTMTATTRW( connection ))
                {
                    if ( statement -> implicit_ard )
                        __release_desc( statement -> implicit_ard );
                    if ( statement -> implicit_apd )
                        __release_desc( statement -> implicit_apd );
                    if ( statement -> implicit_ird )
                        __release_desc( statement -> implicit_ird );
                    if ( statement -> implicit_ipd )
                        __release_desc( statement -> implicit_ipd );
                }
                statement -> connection -> statement_count --;

                thread_release( SQL_HANDLE_STMT, statement );
#if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H )
                uodbc_update_stats(connection->environment->sh,
                                   UODBC_STATS_TYPE_HSTMT, (void *)-1);
#endif

                __release_stmt( statement );
            }
            else
            {
                thread_release( SQL_HANDLE_STMT, statement );
            }

            if ( log_info.log_flag )
            {
                sprintf( connection -> msg,
                        "\n\t\tExit:[SQL_SUCCESS]" );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        connection -> msg );
            }

            return function_return( IGNORE_THREAD, connection, ret ); 
        }
        break;

      case SQL_HANDLE_DESC:
        {
            DMHDESC descriptor = (DMHDESC)handle;
            DMHDBC connection;
            SQLRETURN ret;

            /*
             * check descriptor
             */
            if ( !__validate_desc( descriptor ))
            {
                return SQL_INVALID_HANDLE;
            }

            function_entry( descriptor );

            connection = descriptor -> connection;

            if ( log_info.log_flag )
            {
                sprintf( descriptor -> msg,
                        "\n\t\tEntry:\n\t\t\tHandle Type = %d\n\t\t\tInput Handle = %p",
                        handle_type,
                        (void*)handle );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        descriptor -> msg );
            }

			if ( descriptor -> implicit )
			{
				dm_log_write( __FILE__,
						__LINE__,
						LOG_INFO,
						LOG_INFO,
						"Error: HY017" );
		
				__post_internal_error( &descriptor -> error,
						ERROR_HY017, NULL,
						connection -> environment -> requested_version );
		
				return function_return( IGNORE_THREAD, descriptor, SQL_ERROR );
			}
		
            thread_protect( SQL_HANDLE_DESC, descriptor );

            if ( !CHECK_SQLFREEHANDLE( connection ))
            {
                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        "Error: IM001" );

                __post_internal_error( &descriptor -> error,
                        ERROR_IM001, NULL,
                        connection -> environment -> requested_version );

                return function_return( SQL_HANDLE_DESC, descriptor, SQL_ERROR );
            }
            else
            {
                ret = SQLFREEHANDLE( connection,
                        handle_type,
                        descriptor -> driver_desc );
            }

            /*
             * check status of statements associated with this descriptor
             */

            if( __check_stmt_from_desc( descriptor, STATE_S8 ) ||
                __check_stmt_from_desc( descriptor, STATE_S9 ) ||
                __check_stmt_from_desc( descriptor, STATE_S10 ) ||
                __check_stmt_from_desc( descriptor, STATE_S11 ) ||
                __check_stmt_from_desc( descriptor, STATE_S12 )) {

                dm_log_write( __FILE__, 
                        __LINE__, 
                        LOG_INFO, 
                        LOG_INFO, 
                        "Error: HY010" );

                __post_internal_error( &descriptor -> error,
                        ERROR_HY010, NULL,
                        descriptor -> connection -> environment -> requested_version );

                return function_return( SQL_HANDLE_DESC, descriptor, SQL_ERROR );
            }

            thread_release( SQL_HANDLE_DESC, descriptor );

            __release_desc( descriptor );

            if ( log_info.log_flag )
            {
                sprintf( connection -> msg,
                        "\n\t\tExit:[SQL_SUCCESS]" );

                dm_log_write( __FILE__,
                        __LINE__,
                        LOG_INFO,
                        LOG_INFO,
                        connection -> msg );
            }
#if defined ( COLLECT_STATS ) && defined( HAVE_SYS_SEM_H )
            uodbc_update_stats(connection->environment->sh,
                               UODBC_STATS_TYPE_HDESC, (void *)-1);
#endif

            return function_return( IGNORE_THREAD, connection, SQL_SUCCESS ); 
        }
        break;

      default:
        /*
         * there is nothing to report a error on
         */
        return SQL_ERROR;
    }
}
Beispiel #13
0
int wmain(int argc, wchar_t* argv[], wchar_t* arge[])
{
	std::locale::global(std::locale("", std::locale::ctype));

	SQLRETURN res = SQL_SUCCESS;

	bool bError = true;
	std::wstring strErr(L"");
	SQLSMALLINT errHandleType = 0;
	SQLHANDLE errHandle = SQL_NULL_HANDLE;


	SQLHENV henv = SQL_NULL_HANDLE;
	SQLHDBC hdbc = SQL_NULL_HANDLE;
	SQLHSTMT hstmt = SQL_NULL_HANDLE;

	bool bConnect = false;

	// 環境ハンドルの作成&設定
	res = ::SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
	if(!SQL_SUCCEEDED(res)){strErr = L"環境ハンドル作成";	errHandleType = SQL_HANDLE_ENV;	errHandle = SQL_NULL_HANDLE;	goto end;}
	res = ::SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3), 0);
	if(!SQL_SUCCEEDED(res)){strErr = L"環境ハンドル設定";	errHandleType = SQL_HANDLE_ENV;	errHandle = henv;	goto end;}
	// 接続ハンドルの作成
	res = ::SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
	if(!SQL_SUCCEEDED(res)){strErr = L"接続ハンドル作成";	errHandleType = SQL_HANDLE_ENV;	errHandle = henv;	goto end;}
	// ODBCドライバへ接続
	res = ::SQLDriverConnect(hdbc, NULL, L"DRIVER={SQL Server Native Client 10.0};SERVER=(local);Trusted_Connection=yes;Database=TestDB", SQL_NTS,
		NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
	if(!SQL_SUCCEEDED(res)){strErr = L"接続";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}
	bConnect = true;
	std::wcout << L"接続成功" << std::endl;

	// ステートメントハンドルを作成
	res = ::SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
	if(!SQL_SUCCEEDED(res)){strErr = L"ステートメントハンドル作成";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}

/*	SQLExecute
	// SQL実行
	{	// INSERT
		res = ::SQLPrepareW(hstmt, L"INSERT INTO TestTable(ID, Name, Price) VALUES(?, ?, ?)", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 Prepare";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		int ID = 0;
		SQLLEN nRes_ID = 0;
		res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &ID, 0, &nRes_ID);
		if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 BindParam 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		SQLWCHAR Name[21] = {'0'};
		SQLLEN nRes_Name = SQL_NTS;
		res = ::SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WVARCHAR, 20, 0, Name, 0, &nRes_Name);
		if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 BindParam 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		int Price = 0;
		SQLLEN nRes_Price = 0;
		res = ::SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price, 0, &nRes_Price);
		if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 BindParam 3";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}

		ID = 3;	wcscpy_s(Name, L"サンドイッチ");	Price = 200;
		res = ::SQLExecute(hstmt);
		if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 1 Execute";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		ID = 4;	wcscpy_s(Name, L"カップ麺");	Price = 250;
		res = ::SQLExecute(hstmt);
		if(!SQL_SUCCEEDED(res)){strErr = L"INSERT 2 Execute";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	}
	{	// UPDATE
		res = ::SQLPrepareW(hstmt, L"UPDATE TestTable SET Price=? WHERE Price=?", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 Prepare";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		int Price_After = 0;
		SQLLEN nRes_PriceA = 0;
		res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price_After, 0, &nRes_PriceA);
		if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 BindParam 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		int Price_Before = 0;
		SQLLEN nRes_PriceB = 0;
		res = ::SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price_Before, 0, &nRes_PriceB);
		if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 BindParam 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}

		Price_After = 210;
		Price_Before = 200;
		res = ::SQLExecute(hstmt);
		if(!SQL_SUCCEEDED(res)){strErr = L"UPDATE 1 Execute";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	}
	{	// DELETE
		res = ::SQLPrepareW(hstmt, L"DELETE FROM TestTable WHERE ID>=?", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"DELETE 1 Prepare";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		int ID = 0;
		SQLLEN nRes_ID = 0;
		res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &ID, 0, &nRes_ID);
		if(!SQL_SUCCEEDED(res)){strErr = L"DELETE 1 BindParam 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}

		ID = 3;
		res = ::SQLExecute(hstmt);
		if(!SQL_SUCCEEDED(res)){strErr = L"DELETE 1 Execute";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	}
	{	// SELECT
		res = ::SQLPrepareW(hstmt, L"SELECT * FROM TestTable WHERE Price>=?", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Prepare";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		int Price = 0;
		SQLLEN nRes_Price = 0;
		res = ::SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &Price, 0, &nRes_Price);
		if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 BindParam 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}

		Price = 100;
		res = ::SQLExecute(hstmt);
		if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Execute";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		{
			std::wcout << L"SQL実行 SELECT 1" << std::endl;
			SQLINTEGER id = 0;
			SQLWCHAR name[20 + 1] ={L'\0'};
			SQLINTEGER price = 0;
			SQLLEN len1 = 0;
			SQLLEN len2 = 0;
			SQLLEN len3 = 0;
			res = ::SQLBindCol(hstmt, 1, SQL_C_SLONG, &id, sizeof(id), &len1);
			if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
			res = ::SQLBindCol(hstmt, 2, SQL_C_WCHAR, &name, sizeof(name), &len2);
			if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
			res = ::SQLBindCol(hstmt, 3, SQL_C_SLONG, &price, sizeof(price), &len3);
			if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 3";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
			while(SQL_SUCCEEDED(::SQLFetch(hstmt)))
				std::wcout << id << L", " << name << L", " << price
					<< L" : (" << len1 << L", " << len2 << L", " << len3 << L')' <<  std::endl;
		}
		res = ::SQLCloseCursor(hstmt);
		if(!SQL_SUCCEEDED(res)){strErr = L"Close カーソル SELECT 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	}
*/
/*	SQLExecDirect
	// INSERT
	res = ::SQLExecDirect(hstmt, L"INSERT INTO TestTable(ID, Name, Price) VALUES(3, 'サンドイッチ', 200)", SQL_NTS);
	if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 INSERT 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	{
		SQLLEN cnt = 0;
		res = ::SQLRowCount(hstmt, &cnt);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 INSERT 1 結果列数取得";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		std::wcout << L"SQL実行 INSERT 1 : " << cnt << L" 行  処理されました。" << std::endl;
	}
	// UPDATE
	res = ::SQLExecDirect(hstmt, L"UPDATE TestTable SET Price=250 WHERE Price=200", SQL_NTS);
	if(res == SQL_NO_DATA){std::wcout << L"SQL実行 UPDATE 1 : データがありませんでした。" << std::endl;}
	else if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 UPDATE 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	else
	{
		SQLLEN cnt = 0;
		res = ::SQLRowCount(hstmt, &cnt);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 UPDATE 1 結果列数取得";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		std::wcout << L"SQL実行 UPDATE 1 : " << cnt << L" 行  処理されました。" << std::endl;
	}
	// DELETE
	res = ::SQLExecDirect(hstmt, L"DELETE FROM TestTable WHERE Price=250", SQL_NTS);
	if(res == SQL_NO_DATA){std::wcout << L"SQL実行 DELETE 1 : データがありませんでした。" << std::endl;}
	else if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 DELETE 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	else
	{
		SQLLEN cnt = 0;
		res = ::SQLRowCount(hstmt, &cnt);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 DELETE 1 結果列数取得";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		std::wcout << L"SQL実行 DELETE 1 : " << cnt << L" 行  処理されました。" << std::endl;
	}
	// SELECT
	res = ::SQLExecDirect(hstmt, L"SELECT * FROM TestTable", SQL_NTS);
	if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 SELECT 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	{
		std::wcout << L"SQL実行 SELECT 1" << std::endl;
		SQLINTEGER id = 0;
		SQLWCHAR name[20 + 1] ={L'\0'};
		SQLINTEGER price = 0;
		SQLLEN len1 = 0;
		SQLLEN len2 = 0;
		SQLLEN len3 = 0;
		res = ::SQLBindCol(hstmt, 1, SQL_C_SLONG, &id, sizeof(id), &len1);
		if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLBindCol(hstmt, 2, SQL_C_WCHAR, &name, sizeof(name), &len2);
		if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLBindCol(hstmt, 3, SQL_C_SLONG, &price, sizeof(price), &len3);
		if(!SQL_SUCCEEDED(res)){strErr = L"SELECT 1 Bind 3";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		while(SQL_SUCCEEDED(::SQLFetch(hstmt)))
			std::wcout << id << L", " << name << L", " << price
				<< L" : (" << len1 << L", " << len2 << L", " << len3 << L')' <<  std::endl;
	}
	res = ::SQLCloseCursor(hstmt);
	if(!SQL_SUCCEEDED(res)){strErr = L"Close カーソル SELECT 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
*/

	{	// Auto Commit Off
		res = ::SQLSetConnectAttrW(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_OFF, SQL_IS_UINTEGER);
		if(!SQL_SUCCEEDED(res)){strErr = L"Connect属性セット 1";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}
		// Rollback
		if(!TransactionSequence(hstmt)){strErr = L"TranSeq 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK);
		if(!SQL_SUCCEEDED(res)){strErr = L"Rollback";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}
		// Commit
		if(!TransactionSequence(hstmt)){strErr = L"TranSeq 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
		if(!SQL_SUCCEEDED(res)){strErr = L"Commit";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}
		// Cleanup
		if(!CleanupTranSeq(hstmt)){strErr = L"CleanTranSeq 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT);
		if(!SQL_SUCCEEDED(res)){strErr = L"Commit Cleanup 1";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}
	}
	{	// Auto Commit On
		res = ::SQLSetConnectAttrW(hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER);
		if(!SQL_SUCCEEDED(res)){strErr = L"Connect属性セット 2";	errHandleType = SQL_HANDLE_DBC;	errHandle = hdbc;	goto end;}
		// Rollback Sequence
		res = ::SQLExecDirect(hstmt, L"BEGIN TRANSACTION", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 BEGIN TRANSACTION 1";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		if(!TransactionSequence(hstmt)){strErr = L"TranSeq 3";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLExecDirect(hstmt, L"ROLLBACK TRANSACTION", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 ROLLBACK TRANSACTION 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		// Commit
		res = ::SQLExecDirect(hstmt, L"BEGIN TRANSACTION", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 BEGIN TRANSACTION 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		if(!TransactionSequence(hstmt)){strErr = L"TranSeq 4";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		res = ::SQLExecDirect(hstmt, L"COMMIT TRANSACTION", SQL_NTS);
		if(!SQL_SUCCEEDED(res)){strErr = L"SQL実行 ROLLBACK TRANSACTION 3";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
		// Cleanup
		if(!CleanupTranSeq(hstmt)){strErr = L"CleanTranSeq 2";	errHandleType = SQL_HANDLE_STMT;	errHandle = hstmt;	goto end;}
	}


	std::wcout << L"SQL実行成功" << std::endl;

	bError = false;
end:
	if(bError)
	{
		SQLWCHAR szState[6] = {L'\0'};
		SQLWCHAR szErrorMsg[1024] = {L'\0'};
		SQLINTEGER  nErrorCode = 0;
		SQLSMALLINT nSize = 0;
		::SQLGetDiagRec(errHandleType, errHandle, 1, szState, &nErrorCode, szErrorMsg, sizeof(szErrorMsg), &nSize);
		std::wcout << L"エラー(" << strErr
			<< L") State=[" << szState
			<< L"] ErrorMsg[" << szErrorMsg << L"]" << std::endl;
	}

	if(hstmt != SQL_NULL_HANDLE)	::SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	if(hdbc != SQL_NULL_HANDLE)
	{
		if(bConnect)	::SQLDisconnect(hdbc);
		::SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
	}
	if(henv != SQL_NULL_HANDLE)	::SQLFreeHandle(SQL_HANDLE_ENV, henv);

	std::wcout << L"終了するには何かキーを押してください。" << std::endl;
	_getch();
	return 0;
}
int main(int argc, char **argv)
{
	int rc;
	HSTMT hstmt = SQL_NULL_HSTMT;
	int			i;
	SQLINTEGER	colvalue;
	SQLLEN		indColvalue;

	test_connect();

	rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
	if (!SQL_SUCCEEDED(rc))
	{
		print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
		exit(1);
	}

	/*
	 * Initialize a table with some test data.
	 */
	printf("Creating test table pos_update_test\n");
	rc = SQLExecDirect(hstmt, (SQLCHAR *) "CREATE TEMPORARY TABLE pos_update_test(i int4, orig int4)", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);
	rc = SQLExecDirect(hstmt, (SQLCHAR *) "INSERT INTO pos_update_test SELECT g, g FROM generate_series(1, 10) g", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	printf("Opening a cursor for update, and fetching 10 rows\n");

	rc  = SQLSetStmtAttr(hstmt, SQL_ATTR_CONCURRENCY,
						 (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
	CHECK_STMT_RESULT(rc, "SQLSetStmtAttr failed", hstmt);
	rc = SQLSetStmtAttr(hstmt, SQL_ATTR_CURSOR_TYPE,
						(SQLPOINTER) SQL_CURSOR_KEYSET_DRIVEN, 0);
	CHECK_STMT_RESULT(rc, "SQLSetStmtAttr failed", hstmt);

	rc = SQLBindCol(hstmt, 1, SQL_C_LONG, &colvalue, 0, &indColvalue);
	CHECK_STMT_RESULT(rc, "SQLBindCol failed", hstmt);

	rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT * FROM pos_update_test ORDER BY orig", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);

	for (i = 0; i < 5; i++)
	{
		rc = SQLFetch(hstmt);
		if (rc == SQL_NO_DATA)
			break;
		if (rc == SQL_SUCCESS)
		{
			char buf[40];
			int col;
			SQLLEN ind;

			for (col = 1; col <= 2; col++)
			{
				rc = SQLGetData(hstmt, col, SQL_C_CHAR, buf, sizeof(buf), &ind);
				if (!SQL_SUCCEEDED(rc))
				{
					print_diag("SQLGetData failed", SQL_HANDLE_STMT, hstmt);
					exit(1);
				}
				if (ind == SQL_NULL_DATA)
					strcpy(buf, "NULL");
				printf("%s%s", (col > 1) ? "\t" : "", buf);
			}
			printf("\n");
		}
		else
		{
			print_diag("SQLFetch failed", SQL_HANDLE_STMT, hstmt);
			exit(1);
		}
	}

	/* Do a positioned update and delete */
	printf("Updating result set\n");
	colvalue += 100;
	rc = SQLSetPos(hstmt, 1, SQL_UPDATE, SQL_LOCK_NO_CHANGE);
	CHECK_STMT_RESULT(rc, "SQLSetPos failed", hstmt);

	rc = SQLFetch(hstmt);
	CHECK_STMT_RESULT(rc, "SQLFetch failed", hstmt);

	rc = SQLSetPos(hstmt, 1, SQL_DELETE, SQL_LOCK_NO_CHANGE);
	CHECK_STMT_RESULT(rc, "SQLSetPos failed", hstmt);

	rc = SQLFreeStmt(hstmt, SQL_CLOSE);
	CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);

	/* See if the update took effect */
	rc = SQLExecDirect(hstmt, (SQLCHAR *) "SELECT * FROM pos_update_test ORDER BY orig", SQL_NTS);
	CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);
	print_result(hstmt);

	/* Clean up */
	test_disconnect();

	return 0;
}
Beispiel #15
0
static void *db_iodbc_open_int(TABDCA *dca, int mode, const char
   **sqllines)
{
   struct db_odbc    *sql;
   SQLRETURN          ret;
   SQLCHAR FAR       *dsn;
   SQLCHAR            info[256];
   SQLSMALLINT        colnamelen;
   SQLSMALLINT        nullable;
   SQLSMALLINT        scale;
   const char        *arg;
   int                narg;
   int                i, j;
   int                total;

   if (libodbc == NULL)
   {
      xprintf("No loader for shared ODBC library available\n");
      return NULL;
   }

   if (h_odbc == NULL)
   {
      h_odbc = xdlopen(libodbc);
      if (h_odbc == NULL)
      {  xprintf("unable to open library %s\n", libodbc);
         xprintf("%s\n", xerrmsg());
         return NULL;
      }
   }

   sql = (struct db_odbc *) xmalloc(sizeof(struct db_odbc));
   if (sql == NULL)
         return NULL;

   sql->mode  = mode;
   sql->hdbc  = NULL;
   sql->henv  = NULL;
   sql->hstmt = NULL;
   sql->query = NULL;
   narg = mpl_tab_num_args(dca);

   dsn = (SQLCHAR FAR *) mpl_tab_get_arg(dca, 2);
   /* allocate an environment handle */
   ret = dl_SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
      &(sql->henv));
   /* set attribute to enable application to run as ODBC 3.0
      application */
   ret = dl_SQLSetEnvAttr(sql->henv, SQL_ATTR_ODBC_VERSION,
      (void *) SQL_OV_ODBC3, 0);
   /* allocate a connection handle */
   ret = dl_SQLAllocHandle(SQL_HANDLE_DBC, sql->henv, &(sql->hdbc));
   /* connect */
   ret = dl_SQLDriverConnect(sql->hdbc, NULL, dsn, SQL_NTS, NULL, 0,
      NULL, SQL_DRIVER_COMPLETE);
   if (SQL_SUCCEEDED(ret))
   {  /* output information about data base connection */
      xprintf("Connected to ");
      dl_SQLGetInfo(sql->hdbc, SQL_DBMS_NAME, (SQLPOINTER)info,
         sizeof(info), NULL);
      xprintf("%s ", info);
      dl_SQLGetInfo(sql->hdbc, SQL_DBMS_VER, (SQLPOINTER)info,
         sizeof(info), NULL);
      xprintf("%s - ", info);
      dl_SQLGetInfo(sql->hdbc, SQL_DATABASE_NAME, (SQLPOINTER)info,
         sizeof(info), NULL);
      xprintf("%s\n", info);
   }
   else
   {  /* describe error */
      xprintf("Failed to connect\n");
      extract_error("SQLDriverConnect", sql->hdbc, SQL_HANDLE_DBC);
      dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
      dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
      xfree(sql);
      return NULL;
   }
   /* set AUTOCOMMIT on*/
   ret = dl_SQLSetConnectAttr(sql->hdbc, SQL_ATTR_AUTOCOMMIT,
      (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0);
   /* allocate a statement handle */
   ret = dl_SQLAllocHandle(SQL_HANDLE_STMT, sql->hdbc, &(sql->hstmt));

   /* initialization queries */
   for(j = 0; sqllines[j+1] != NULL; j++)
   {
      sql->query = (SQLCHAR *) sqllines[j];
      xprintf("%s\n", sql->query);
      ret = dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS);
      switch (ret)
      {
         case SQL_SUCCESS:
         case SQL_SUCCESS_WITH_INFO:
         case SQL_NO_DATA_FOUND:
            break;
         default:
            xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n",
               sql->query);
            extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT);
            dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
            dl_SQLDisconnect(sql->hdbc);
            dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
            dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
            xfree(sql);
            return NULL;
      }
      /* commit statement */
      dl_SQLEndTran(SQL_HANDLE_ENV, sql->henv, SQL_COMMIT);
   }

   if ( sql->mode == 'R' )
   {  sql->nf = mpl_tab_num_flds(dca);
      for(j = 0; sqllines[j] != NULL; j++)
         arg = sqllines[j];
      total = strlen(arg);
      if (total > 7 && 0 == strncmp(arg, "SELECT ", 7))
      {
         total = strlen(arg);
         sql->query = xmalloc( (total+1) * sizeof(char));
         strcpy (sql->query, arg);
      }
      else
      {
         sql->query = db_generate_select_stmt(dca);
      }
      xprintf("%s\n", sql->query);
      if (dl_SQLExecDirect(sql->hstmt, sql->query, SQL_NTS) !=
         SQL_SUCCESS)
      {
         xprintf("db_iodbc_open: Query\n\"%s\"\nfailed.\n", sql->query);
         extract_error("SQLExecDirect", sql->hstmt, SQL_HANDLE_STMT);
         dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
         dl_SQLDisconnect(sql->hdbc);
         dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
         dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
         xfree(sql->query);
            xfree(sql);
         return NULL;
      }
      xfree(sql->query);
      /* determine number of result columns */
      ret = dl_SQLNumResultCols(sql->hstmt, &sql->nresultcols);
      total = sql->nresultcols;
      if (total > SQL_FIELD_MAX)
      {  xprintf("db_iodbc_open: Too many fields (> %d) in query.\n"
            "\"%s\"\n", SQL_FIELD_MAX, sql->query);
         dl_SQLFreeHandle(SQL_HANDLE_STMT, sql->hstmt);
         dl_SQLDisconnect(sql->hdbc);
         dl_SQLFreeHandle(SQL_HANDLE_DBC, sql->hdbc);
         dl_SQLFreeHandle(SQL_HANDLE_ENV, sql->henv);
         xfree(sql->query);
         return NULL;
      }
      for (i = 1; i <= total; i++)
      {  /* return a set of attributes for a column */
         ret = dl_SQLDescribeCol(sql->hstmt, (SQLSMALLINT) i,
            sql->colname[i], SQL_FDLEN_MAX,
            &colnamelen, &(sql->coltype[i]), &(sql->collen[i]), &scale,
            &nullable);
         sql->isnumeric[i] = is_numeric(sql->coltype[i]);
         /* bind columns to program vars, converting all types to CHAR*/
         if (sql->isnumeric[i])
         {  dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i],
               SQL_FDLEN_MAX, &(sql->outlen[i]));
         } else
         {  dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i],
               SQL_FDLEN_MAX, &(sql->outlen[i]));
         }
         for (j = sql->nf; j >= 1; j--)
         {  if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0)
            break;
         }
         sql->ref[i] = j;
      }
   }
   else if ( sql->mode == 'W' )
   {  for(j = 0; sqllines[j] != NULL; j++)
         arg = sqllines[j];
      if (  NULL != strchr(arg, '?') )
      {
         total = strlen(arg);
         sql->query = xmalloc( (total+1) * sizeof(char));
         strcpy (sql->query, arg);
         }
      else
      {
         sql->query = db_generate_insert_stmt(dca);
      }
      xprintf("%s\n", sql->query);
   }
   return sql;
}
Beispiel #16
0
//*************************************************************************
int main()
{
  SQLHENV env;
  SQLHDBC dbc;
  SQLHSTMT stmt;
  SQLRETURN ret;
  SQLCHAR outstr[1024];
  SQLSMALLINT outstrlen;
  
  // Aloocate an environment handle
  ret=SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&env);
  checkrc(ret,__LINE__);
  
   //we need odbc3 support
   SQLSetEnvAttr(env,SQL_ATTR_ODBC_VERSION,(void*)SQL_OV_ODBC3,0);
   
  //ALLOCATE A Connection handle
  ret = SQLAllocHandle(SQL_HANDLE_DBC,env,&dbc);
  checkrc(ret,__LINE__);
    
  // connect to the DSN mydsn
   ret = SQLConnect (dbc,
                   (SQLCHAR *) "DSN=mycsql;MODE=csql;SERVER=localhost;PORT=5678;", (SQLSMALLINT) strlen ("DSN=mycsql;MODE=csql;SERVER=localhost;PORT=5678;"),
                   (SQLCHAR *) "root",
                   (SQLSMALLINT) strlen ("root"),
                   (SQLCHAR *) "manager",
                   (SQLSMALLINT) strlen (""));


  if(SQL_SUCCEEDED(ret))
  {
     printf("\nConnected to the Data Source..\n");
       
     
  }
   else
   {
        printf("connection failed\n");
        ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc);
        checkrc(ret,__LINE__); 
        ret = SQLFreeHandle(SQL_HANDLE_ENV,env);
        checkrc(ret,__LINE__);
        return 1;
   }

   ret = SQLAllocHandle(SQL_HANDLE_STMT,dbc,&stmt);
   checkrc(ret,__LINE__);

   SQLCHAR table[100]="CREATE TABLE EMP(EID INT,SALARY INT)";
   
   ret = SQLPrepare(stmt,table,SQL_NTS);
   checkrc(ret,__LINE__);

   ret = SQLDisconnect(dbc);
   checkrc(ret,__LINE__);
   
   //AFTER CLOSE THE CONNECTION ,CALL execute
      
   ret = SQLExecute(stmt);
   int rettype = ret;
   if(ret )
   printf("After closing the connection, Execution failed\n"); 
   
      
   ret = SQLFreeHandle(SQL_HANDLE_DBC,dbc);
   checkrc(ret,__LINE__);
   
   ret = SQLFreeHandle(SQL_HANDLE_ENV,env);
   checkrc(ret,__LINE__);
  
   if(rettype ==0)return 1;
     

  return 0;
}         
Beispiel #17
0
static bool Connect(PyObject* pConnectString, HDBC hdbc, bool fAnsi, long timeout)
{
    // This should have been checked by the global connect function.
    I(PyString_Check(pConnectString) || PyUnicode_Check(pConnectString));

    const int cchMax = 600;

    if (PySequence_Length(pConnectString) >= cchMax)
    {
        PyErr_SetString(PyExc_TypeError, "connection string too long");
        return false;
    }

    // The driver manager determines if the app is a Unicode app based on whether we call SQLDriverConnectA or
    // SQLDriverConnectW.  Some drivers, notably Microsoft Access/Jet, change their behavior based on this, so we try
    // the Unicode version first.  (The Access driver only supports Unicode text, but SQLDescribeCol returns SQL_CHAR
    // instead of SQL_WCHAR if we connect with the ANSI version.  Obviously this causes lots of errors since we believe
    // what it tells us (SQL_CHAR).)

    // Python supports only UCS-2 and UCS-4, so we shouldn't need to worry about receiving surrogate pairs.  However,
    // Windows does use UCS-16, so it is possible something would be misinterpreted as one.  We may need to examine
    // this more.

    SQLRETURN ret;

    if (timeout > 0)
    {
        //Py_BEGIN_ALLOW_THREADS
        ret = SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)timeout, SQL_IS_UINTEGER);
        //Py_END_ALLOW_THREADS
        if (!SQL_SUCCEEDED(ret))
            RaiseErrorFromHandle("SQLSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT)", hdbc, SQL_NULL_HANDLE);
    }

    if (!fAnsi)
    {
        SQLWChar connectString(pConnectString);
        //Py_BEGIN_ALLOW_THREADS
        ret = SQLDriverConnectW(hdbc, 0, connectString.get(), (SQLSMALLINT)connectString.size(), 0, 0, 0, SQL_DRIVER_NOPROMPT);
        //Py_END_ALLOW_THREADS
        if (SQL_SUCCEEDED(ret))
            return true;
        RaiseErrorFromHandle("SQLDriverConnect", hdbc, SQL_NULL_HANDLE);
        return false;

        // The Unicode function failed.  If the error is that the driver doesn't have a Unicode version (IM001), continue
        // to the ANSI version.
        //
        // I've commented this out since a number of common drivers are returning different errors.  The MySQL 5
        // driver, for example, returns IM002 "Data source name not found...".
        //
        // PyObject* error = GetErrorFromHandle("SQLDriverConnectW", hdbc, SQL_NULL_HANDLE);
        // if (!HasSqlState(error, "IM001"))
        // {
        //     RaiseErrorFromException(error);
        //     return false;
        // }
        // Py_XDECREF(error);
    }
    PyErr_SetString(PyExc_TypeError, "Non-unicode connection strings not supported.");
    return false;
}
Beispiel #18
0
CSqlRecordsetPtr CDb2Connection::_Execute(const char *string)
{
	SQLRETURN ret;

	CDb2Recordset *rs = new CDb2Recordset();

	CServerIo::trace(3,"%s",string);

	HSTMT hStmt;

	if(!SQL_SUCCEEDED(m_lasterror=SQLAllocHandle(SQL_HANDLE_STMT,m_hDbc,&hStmt)))
	{
		SQLFreeStmt(hStmt,SQL_DROP);
		return rs;
	}

	for(std::map<int,CSqlVariant>::iterator i = m_bindVars.begin(); i!=m_bindVars.end(); ++i)
	{
		switch(i->second.type())
		{
		case CSqlVariant::vtNull:
			m_sqli[i->first]=SQL_NULL_DATA;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,0,0,NULL,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtChar:
			m_sqli[i->first]=0;
			m_sqlv[i->first].c=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,1,0,&m_sqlv[i->first].c,1,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtUChar:
			m_sqli[i->first]=0;
			m_sqlv[i->first].c=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_CHAR,SQL_CHAR,1,0,&m_sqlv[i->first].c,1,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtShort:
			m_sqli[i->first]=0;
			m_sqlv[i->first].s=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_SSHORT,SQL_INTEGER,0,0,&m_sqlv[i->first].s,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtUShort:
			m_sqli[i->first]=0;
			m_sqlv[i->first].s=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_USHORT,SQL_INTEGER,0,0,&m_sqlv[i->first].s,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtInt:
		case CSqlVariant::vtLong:
			m_sqli[i->first]=0;
			m_sqlv[i->first].l=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,&m_sqlv[i->first].l,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtUInt:
		case CSqlVariant::vtULong:
			m_sqli[i->first]=0;
			m_sqlv[i->first].l=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&m_sqlv[i->first].l,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtLongLong:
			m_sqli[i->first]=0;
			m_sqlv[i->first].ll=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_SBIGINT,SQL_BIGINT,0,0,&m_sqlv[i->first].ll,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtULongLong:
			m_sqli[i->first]=0;
			m_sqlv[i->first].ll=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_UBIGINT,SQL_BIGINT,0,0,&m_sqlv[i->first].ll,0,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtString:
			m_sqli[i->first]=SQL_NTS;
			m_sqlv[i->first].ws=cvs::wide(i->second);
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_WCHAR,SQL_WVARCHAR,(SQLINTEGER)m_sqlv[i->first].ws.size()+1,0,(SQLPOINTER)m_sqlv[i->first].ws.c_str(),(SQLINTEGER)m_sqlv[i->first].ws.size()+1,&m_sqli[i->first]);
			break;
		case CSqlVariant::vtWString:
			m_sqli[i->first]=SQL_NTS;
			m_sqlv[i->first].ws=i->second;
			ret = SQLBindParameter(hStmt,i->first+1,SQL_PARAM_INPUT,SQL_C_WCHAR,SQL_WVARCHAR,(SQLINTEGER)m_sqlv[i->first].ws.size()+1,0,(SQLPOINTER)m_sqlv[i->first].ws.c_str(),(SQLINTEGER)m_sqlv[i->first].ws.size()+1,&m_sqli[i->first]);
			break;
		}
	}

	rs->Init(this,hStmt,string); // Ignore return... it's handled by the error routines

	m_bindVars.clear();

	return rs;
}
Beispiel #19
0
/*
 *  Show all the error information that is available
 */
int
ODBC_Errors (char *where)
{
  SQLTCHAR buf[512];
  SQLTCHAR sqlstate[15];
  SQLINTEGER native_error = 0;
  int force_exit = 0;
  SQLRETURN sts;

#if (ODBCVER < 0x0300)
  /*
   *  Get statement errors
   */
  while (hstmt)
    {
      sts = SQLError (henv, hdbc, hstmt, sqlstate, &native_error,
	  buf, NUMTCHAR (buf), NULL);
      if (!SQL_SUCCEEDED (sts))
	break;

#ifdef UNICODE
      fprintf (stderr, "%s = %S (%ld) SQLSTATE=%S\n",
	  where, buf, (long) native_error, sqlstate);
#else
      fprintf (stderr, "%s = %s (%ld) SQLSTATE=%s\n",
	  where, buf, (long) native_error, sqlstate);
#endif

      /*
       *  If the driver could not be loaded, there is no point in
       *  continuing, after reading all the error messages
       */
      if (!TXTCMP (sqlstate, TEXT ("IM003")))
	force_exit = 1;
    }

  /*
   *  Get connection errors
   */
  while (hdbc)
    {
      sts = SQLError (henv, hdbc, SQL_NULL_HSTMT, sqlstate, &native_error,
	  buf, NUMTCHAR (buf), NULL);
      if (!SQL_SUCCEEDED (sts))
	break;

#ifdef UNICODE
      fprintf (stderr, "%s = %S (%ld) SQLSTATE=%S\n",
	  where, buf, (long) native_error, sqlstate);
#else
      fprintf (stderr, "%s = %s (%ld) SQLSTATE=%s\n",
	  where, buf, (long) native_error, sqlstate);
#endif

      /*
       *  If the driver could not be loaded, there is no point in
       *  continuing, after reading all the error messages
       */
      if (!TXTCMP (sqlstate, TEXT ("IM003")))
	force_exit = 1;
    }

  /*
   *  Get environment errors
   */
  while (henv)
    {
      sts SQLError (henv, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlstate,
	  &native_error, buf, NUMTCHAR (buf), NULL);
      if (!SQL_SUCCEEDED (sts))
	break;

#ifdef UNICODE
      fprintf (stderr, "%s = %S (%ld) SQLSTATE=%S\n",
	  where, buf, (long) native_error, sqlstate);
#else
      fprintf (stderr, "%s = %s (%ld) SQLSTATE=%s\n",
	  where, buf, (long) native_error, sqlstate);
#endif

      /*
       *  If the driver could not be loaded, there is no point in
       *  continuing, after reading all the error messages
       */
      if (!TXTCMP (sqlstate, TEXT ("IM003")))
	force_exit = 1;
    }
#else /* ODBCVER */
  int i;

  /*
   *  Get statement errors
   */
  i = 0;
  while (hstmt && i < 5)
    {
      sts = SQLGetDiagRec (SQL_HANDLE_STMT, hstmt, ++i,
	  sqlstate, &native_error, buf, NUMTCHAR (buf), NULL);
      if (!SQL_SUCCEEDED (sts))
	break;

#ifdef UNICODE
      fprintf (stderr, "%d: %s = %S (%ld) SQLSTATE=%S\n",
	  i, where, buf, (long) native_error, sqlstate);
#else
      fprintf (stderr, "%d: %s = %s (%ld) SQLSTATE=%s\n",
	  i, where, buf, (long) native_error, sqlstate);
#endif

      /*
       *  If the driver could not be loaded, there is no point in
       *  continuing, after reading all the error messages
       */
      if (!TXTCMP (sqlstate, TEXT ("IM003")))
	force_exit = 1;
    }

  /*
   *  Get connection errors
   */
  i = 0;
  while (hdbc && i < 5)
    {
      sts = SQLGetDiagRec (SQL_HANDLE_DBC, hdbc, ++i,
	  sqlstate, &native_error, buf, NUMTCHAR (buf), NULL);
      if (!SQL_SUCCEEDED (sts))
	break;

#ifdef UNICODE
      fprintf (stderr, "%d: %s = %S (%ld) SQLSTATE=%S\n",
	  i, where, buf, (long) native_error, sqlstate);
#else
      fprintf (stderr, "%d: %s = %s (%ld) SQLSTATE=%s\n",
	  i, where, buf, (long) native_error, sqlstate);
#endif

      /*
       *  If the driver could not be loaded, there is no point in
       *  continuing, after reading all the error messages
       */
      if (!TXTCMP (sqlstate, TEXT ("IM003")))
	force_exit = 1;
    }

  /*
   *  Get environment errors
   */
  i = 0;
  while (henv && i < 5)
    {
      sts = SQLGetDiagRec (SQL_HANDLE_ENV, henv, ++i,
	  sqlstate, &native_error, buf, NUMTCHAR (buf), NULL);
      if (!SQL_SUCCEEDED (sts))
	break;

#ifdef UNICODE
      fprintf (stderr, "%d: %s = %S (%ld) SQLSTATE=%S\n",
	  i, where, buf, (long) native_error, sqlstate);
#else
      fprintf (stderr, "%d: %s = %s (%ld) SQLSTATE=%s\n",
	  i, where, buf, (long) native_error, sqlstate);
#endif

      /*
       *  If the driver could not be loaded, there is no point in
       *  continuing, after reading all the error messages
       */
      if (!TXTCMP (sqlstate, TEXT ("IM003")))
	force_exit = 1;
    }
#endif /* ODBCVER */

  /*
   *  Force an exit status
   */
  if (force_exit)
    exit (-1);

  return -1;
}
Beispiel #20
0
bool CDb2Connection::Error() const
{
	if(SQL_SUCCEEDED(m_lasterror))
		return false;
	return true;
}
Beispiel #21
0
/*
 * Send an SQL query to the server
 */
static int db_unixodbc_submit_query(const db1_con_t* _h, const str* _s)
{
	int ret = 0;
	SQLCHAR sqlstate[7];

	if (!_h || !_s || !_s->s) {
		LM_ERR("invalid parameter value\n");
		return -1;
	}

	/* first do some cleanup if required */
	if(CON_RESULT(_h))
	{
		SQLCloseCursor(CON_RESULT(_h));
		SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h));
	}

	ret = SQLAllocHandle(SQL_HANDLE_STMT, CON_CONNECTION(_h), &CON_RESULT(_h));
	if (!SQL_SUCCEEDED(ret))
	{
		LM_ERR("statement allocation error %d\n",
				(int)(long)CON_CONNECTION(_h));
		db_unixodbc_extract_error("SQLAllocStmt", CON_CONNECTION(_h), SQL_HANDLE_DBC,
			(char*)sqlstate);

		/* Connection broken */
		if( !strncmp((char*)sqlstate,"08003",5) ||
		!strncmp((char*)sqlstate,"08S01",5) ) {
			ret = reconnect(_h);
			if( !SQL_SUCCEEDED(ret) ) return ret;
		} else {
			return ret;
		}
	}

	ret=SQLExecDirect(CON_RESULT(_h),  (SQLCHAR*)_s->s, _s->len);

        /* Handle SQL_NO_DATA as a valid return code. DELETE and UPDATE statements may return this return code if nothing was deleted/updated. */
        if (!SQL_SUCCEEDED(ret) && (ret != SQL_NO_DATA))
	{
		SQLCHAR sqlstate[7];
		LM_ERR("rv=%d. Query= %.*s\n", ret, _s->len, _s->s);
		db_unixodbc_extract_error("SQLExecDirect", CON_RESULT(_h), SQL_HANDLE_STMT,
			(char*)sqlstate);

		/* Connection broken */
		if( !strncmp((char*)sqlstate,"08003",5) ||
		    !strncmp((char*)sqlstate,"08S01",5) ||
		    !strncmp((char*)sqlstate,"HY000",5)   /* ODBC 3 General error */
		    )
		{
			ret = reconnect(_h);
			if( SQL_SUCCEEDED(ret) ) {
				/* Try again */
				ret=SQLExecDirect(CON_RESULT(_h),  (SQLCHAR*)_s->s, _s->len);
				if (!SQL_SUCCEEDED(ret)) {
					LM_ERR("rv=%d. Query= %.*s\n", ret, _s->len, _s->s);
					db_unixodbc_extract_error("SQLExecDirect", CON_RESULT(_h),
						SQL_HANDLE_STMT, (char*)sqlstate);
					/* Close the cursor */
					SQLCloseCursor(CON_RESULT(_h));
					SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h));
				}
			}

		}
		else {
			/* Close the cursor */
			SQLCloseCursor(CON_RESULT(_h));
			SQLFreeHandle(SQL_HANDLE_STMT, CON_RESULT(_h));
		}
	}
	/* Store the ODBC query result */
	CON_QUERY_RESULT(_h) = ret;
	return ret;
}
bool CMssqlRecordset::Init(CMssqlConnection *parent, HSTMT hStmt, const char *command)
{
    m_bEof = false;
    m_parent = parent;
    m_hStmt = hStmt;

    m_parent->m_lasterror=SQLExecDirect(m_hStmt,(SQLWCHAR*)(const wchar_t *)cvs::wide(command),SQL_NTS);
    CServerIo::trace(1,"MSSQL Execute Done");

    if((!SQL_SUCCEEDED(m_parent->m_lasterror))&&(m_parent->m_lasterror!=SQL_NEED_DATA))
    {
        GetStmtError();
        return false;
    }

    if(m_parent->m_lasterror==SQL_NEED_DATA)
    {
        SQLPOINTER pParmID;
        SQLRETURN retcode=SQL_SUCCESS, putret;
        char *dataptr, *dataput;
        SQLINTEGER dataoff, datasiz;
        SQLINTEGER chunk=1024;

        CServerIo::trace(1,"MSSQL Execute requires more data");
        retcode = SQLParamData(m_hStmt, &pParmID);
        if (retcode == SQL_NEED_DATA)
        {
            for(std::map<int,CSqlVariant>::iterator i = parent->m_bindVars.begin(); i!=parent->m_bindVars.end(); ++i)
            {
                switch(i->second.type())
                {
                case CSqlVariant::vtString:
                    if (parent->m_sqlv[i->first].ws.length()+1<256)
                        CServerIo::trace(1,"MSSQL Execute this parameter is too small to be a BLOB");
                    else
                    {
                        //dataput = (char *)((const char *)parent->m_sqlv[i->first].cs.c_str());
                        //dataoff=0; datasiz = (SQLINTEGER)(parent->m_sqlv[i->first].cs.size()+1);
                        dataput = (char *)((const char *)parent->m_sqlv[i->first].ws.c_str());
                        dataoff=0;
                        datasiz = (SQLINTEGER)(parent->m_sqlv[i->first].ws.size()+1);

                        //CServerIo::trace(1,"MSSQL Needs data - so put the data %d, size %d",(int)i->first,(int)parent->m_sqlv[i->first].cs.size()+1);
                        CServerIo::trace(1,"MSSQL Needs data - so put the data %d, size %d",(int)i->first,(int)parent->m_sqlv[i->first].ws.size()+1);
                        for (dataptr=dataput; dataoff<datasiz; dataoff+=chunk)
                        {
                            CServerIo::trace(1,"MSSQL put data %d offset %d bytes N\"%0.25s...%0.25s\"",dataoff,
                                             (dataoff+chunk>datasiz)?datasiz-dataoff:chunk,
                                             (const char *)cvs::narrow((const wchar_t *)(dataptr+dataoff)),
                                             ((const char *)cvs::narrow((const wchar_t *)(dataptr+dataoff))+(((dataoff+chunk>datasiz)?datasiz-dataoff:chunk)+1-25)));
                            putret=SQLPutData(m_hStmt, (SQLPOINTER)(dataptr+(sizeof(wchar_t)*dataoff)), (dataoff+chunk>datasiz)?(sizeof(wchar_t)*(datasiz-dataoff)):(sizeof(wchar_t)*chunk));
                            if(!SQL_SUCCEEDED(putret))
                            {
                                m_parent->m_lasterror = putret;
                                GetStmtError();
                                return false;
                            }
                            /*switch (putret)
                            {
                            case SQL_SUCCESS:
                            	CServerIo::trace(1,"SQL Put Data returned SQL_SUCCESS");
                            	break;
                            case SQL_SUCCESS_WITH_INFO:
                            	CServerIo::trace(1,"SQL Put Data returned SQL_SUCCESS_WITH_INFO");
                            	break;
                            case SQL_STILL_EXECUTING:
                            	CServerIo::trace(1,"SQL Put Data returned SQL_STILL_EXECUTING");
                            	break;
                            case SQL_ERROR:
                            	CServerIo::trace(1,"SQL Put Data returned SQL_ERROR");
                            	break;
                            case SQL_INVALID_HANDLE:
                            	CServerIo::trace(1,"SQL Put Data returned SQL_INVALID_HANDLE");
                            	break;
                            default:
                            	CServerIo::trace(1,"SQL Put Data returned some other error.");
                            }*/
                        }
                        CServerIo::trace(1,"MSSQL call ParamData again");
                        retcode = SQLParamData(m_hStmt, &pParmID);
                        if (retcode==SQL_SUCCESS)
                            CServerIo::trace(1,"MSSQL call ParamData returned OK - no more data");
                        else if (retcode==SQL_NEED_DATA)
                            CServerIo::trace(1,"MSSQL call ParamData returned need more data");
                    }
                    break;
                default:
                    break;
                }
            }
        } else {
            retcode=SQL_SUCCESS;
        }
        if (retcode==SQL_SUCCESS)
            CServerIo::trace(1,"MSSQL call ParamData returned OK - no more data");
        else if (retcode==SQL_NEED_DATA)
            CServerIo::trace(1,"MSSQL call ParamData returned need more data");
        else if(!SQL_SUCCEEDED(retcode))
        {
            CServerIo::trace(1,"MSSQL call ParamData returned some sort of failure so returning...");
            m_parent->m_lasterror = retcode;
            GetStmtError();
            return false;
        }
    }

    CServerIo::trace(1,"MSSQL Execute all complete now get the Number of Result Columns");
    if(!SQL_SUCCEEDED(m_parent->m_lasterror = SQLNumResultCols(m_hStmt,&m_num_fields)))
    {
        GetStmtError();
        return false;
    }

    m_sqlfields.resize(m_num_fields);
    for(SQLSMALLINT n=0; n<m_num_fields; n++)
    {
        SQLRETURN rc;

        SQLWCHAR szCol[128];
        SQLSMALLINT len = sizeof(szCol);
        rc = m_parent->m_lasterror = SQLDescribeCol(hStmt,n+1,szCol,sizeof(szCol),&len,&m_sqlfields[n].type,&m_sqlfields[n].size,&m_sqlfields[n].decimal,&m_sqlfields[n].null);
        if(!SQL_SUCCEEDED(rc))
        {
            GetStmtError();
            return false;
        }
        szCol[len]='\0';
        m_sqlfields[n].field = n;
        m_sqlfields[n].hStmt = m_hStmt;
        m_sqlfields[n].name = szCol;

        SQLINTEGER fldlen = 0;
        SQLSMALLINT ctype;
        switch(m_sqlfields[n].type)
        {
        case SQL_UNKNOWN_TYPE:
            CServerIo::trace(1,"Unable to bind column %s as it is SQL_UNKNOWN_TYPE",(const char *)szCol);
            break; // Don't bind
        case SQL_CHAR:
        case SQL_VARCHAR:
            ctype = SQL_C_WCHAR;
            fldlen = m_sqlfields[n].size;
            break;
        case SQL_DECIMAL:
            ctype = SQL_C_WCHAR;
            fldlen = m_sqlfields[n].size + m_sqlfields[n].decimal + 1;
            break;
        case SQL_NUMERIC:
        case SQL_INTEGER:
        case SQL_SMALLINT:
            ctype = SQL_C_LONG;
            fldlen = sizeof(long);
            break;
        case SQL_FLOAT:
        case SQL_REAL:
        case SQL_DOUBLE:
            ctype = SQL_C_DOUBLE;
            fldlen = sizeof(double);
            break;
        case SQL_DATETIME:
            ctype = SQL_C_WCHAR;
            fldlen = 64;
            break;
        }
        m_sqlfields[n].ctype = ctype;
        m_sqlfields[n].fldlen = fldlen;
        if(m_sqlfields[n].fldlen)
        {
            m_sqlfields[n].data = malloc(m_sqlfields[n].fldlen);
            if(!SQL_SUCCEEDED(m_parent->m_lasterror = SQLBindCol(m_hStmt,n+1,m_sqlfields[n].ctype,m_sqlfields[n].data,m_sqlfields[n].fldlen,&m_sqlfields[n].datalen)))
            {
                GetStmtError();
                CServerIo::trace(1,"Unable to bind column %s due to error",(const char*)szCol);
                return false;
            }
        }
    }

    if(m_num_fields)
    {
        if(!Next() && !m_bEof)
            return false;
    }

    return true;
}
Beispiel #23
0
SQLRETURN SQL_API
SQLBindCol(SQLHSTMT StatementHandle,
	   SQLUSMALLINT ColumnNumber,
	   SQLSMALLINT TargetType,
	   SQLPOINTER TargetValuePtr,
	   SQLLEN BufferLength,
	   SQLLEN *StrLen_or_Ind)
{
	ODBCStmt *stmt = (ODBCStmt *) StatementHandle;
	ODBCDesc *desc;		/* Application Row Descriptor */

#ifdef ODBCDEBUG
	ODBCLOG("SQLBindCol " PTRFMT " %u %s " LENFMT "\n",
		PTRFMTCAST StatementHandle, (unsigned int) ColumnNumber,
		translateCType(TargetType), LENCAST BufferLength);
#endif

	if (!isValidStmt(stmt))
		 return SQL_INVALID_HANDLE;

	assert(stmt->Dbc);

	clearStmtErrors(stmt);

	/* check input parameters */
	/* column number 0 (Bookmark column) is not supported */
	if (ColumnNumber == 0) {
		if (TargetType == SQL_C_BOOKMARK || TargetType == SQL_C_VARBOOKMARK) {
			/* Optional feature not implemented */
			addStmtError(stmt, "HYC00", NULL, 0);
		} else {
			/* Restricted data type attribute violation */
			addStmtError(stmt, "07006", NULL, 0);
		}
		return SQL_ERROR;
	}
	if (stmt->State >= EXECUTED1 && ColumnNumber > stmt->ImplRowDescr->sql_desc_count) {
		/* Invalid descriptor index */
		addStmtError(stmt, "07009", NULL, 0);
		return SQL_ERROR;
	}

	/* For safety: limit the maximum number of columns to bind */
	if (ColumnNumber > MONETDB_MAX_BIND_COLS) {
		/* General error */
		addStmtError(stmt, "HY000", "Maximum number of bind columns (8192) exceeded", 0);
		return SQL_ERROR;
	}

	/* can't let SQLSetDescField below do this check since it
	   returns the wrong error code if the type is incorrect */
	switch (TargetType) {
	case SQL_C_CHAR:
	case SQL_C_WCHAR:
	case SQL_C_BINARY:
	case SQL_C_BIT:
	case SQL_C_STINYINT:
	case SQL_C_UTINYINT:
	case SQL_C_TINYINT:
	case SQL_C_SSHORT:
	case SQL_C_USHORT:
	case SQL_C_SHORT:
	case SQL_C_SLONG:
	case SQL_C_ULONG:
	case SQL_C_LONG:
	case SQL_C_SBIGINT:
	case SQL_C_UBIGINT:
	case SQL_C_NUMERIC:
	case SQL_C_FLOAT:
	case SQL_C_DOUBLE:
	case SQL_C_TYPE_DATE:
	case SQL_C_TYPE_TIME:
	case SQL_C_TYPE_TIMESTAMP:
	case SQL_C_INTERVAL_YEAR:
	case SQL_C_INTERVAL_MONTH:
	case SQL_C_INTERVAL_YEAR_TO_MONTH:
	case SQL_C_INTERVAL_DAY:
	case SQL_C_INTERVAL_HOUR:
	case SQL_C_INTERVAL_MINUTE:
	case SQL_C_INTERVAL_SECOND:
	case SQL_C_INTERVAL_DAY_TO_HOUR:
	case SQL_C_INTERVAL_DAY_TO_MINUTE:
	case SQL_C_INTERVAL_DAY_TO_SECOND:
	case SQL_C_INTERVAL_HOUR_TO_MINUTE:
	case SQL_C_INTERVAL_HOUR_TO_SECOND:
	case SQL_C_INTERVAL_MINUTE_TO_SECOND:
	case SQL_C_GUID:
	case SQL_C_DEFAULT:
		break;
	default:
		/* Invalid application buffer type */
		addStmtError(stmt, "HY003", NULL, 0);
		return SQL_ERROR;
	}

	if (BufferLength < 0) {
		/* Invalid string or buffer length */
		addStmtError(stmt, "HY090", NULL, 0);
		return SQL_ERROR;
	}

	desc = stmt->ApplRowDescr;

	if (TargetValuePtr == NULL && ColumnNumber == desc->sql_desc_count) {
		int i = desc->sql_desc_count - 1;

		while (i > 0 && desc->descRec[i].sql_desc_data_ptr == NULL)
			i--;
		setODBCDescRecCount(desc, i);
	} else {
		ODBCDescRec *rec;
		SQLRETURN rc;

		if (ColumnNumber > desc->sql_desc_count)
			setODBCDescRecCount(desc, ColumnNumber);
		rc = SQLSetDescField_(desc, ColumnNumber, SQL_DESC_CONCISE_TYPE, (SQLPOINTER) (ssize_t) TargetType, 0);
		if (!SQL_SUCCEEDED(rc))
			return rc;
		rec = &desc->descRec[ColumnNumber];
		rec->sql_desc_octet_length = BufferLength;
		rec->sql_desc_data_ptr = TargetValuePtr;
		rec->sql_desc_indicator_ptr = StrLen_or_Ind;
		rec->sql_desc_octet_length_ptr = StrLen_or_Ind;
	}

	return SQL_SUCCESS;
}
Beispiel #24
0
bool CQuery::BindParameter( _In_ SQLUSMALLINT parameterNumber, _In_ SQLSMALLINT inputOutputType, _In_ SQLSMALLINT valueType, _In_ SQLSMALLINT parameterType, _In_ SQLUINTEGER columnSize, _In_ SQLSMALLINT decimalDigits, _In_ SQLPOINTER  parameterValuePtr, _In_ SQLINTEGER bufferLength, _In_ SQLINTEGER *strLen_or_IndPtr )
{
	return SQL_SUCCEEDED( SQLBindParameter( m_hStmt, parameterNumber, inputOutputType, valueType, parameterType, columnSize, decimalDigits, parameterValuePtr, bufferLength, strLen_or_IndPtr ) );
}
Beispiel #25
0
SQLRETURN SQLExecDirectW( SQLHSTMT statement_handle,
           SQLWCHAR *statement_text,
           SQLINTEGER text_length )
{
    DMHSTMT statement = (DMHSTMT) statement_handle;
    SQLRETURN ret;
    SQLCHAR *s1;
    SQLCHAR s2[ 100 + LOG_MESSAGE_LEN ];

    /*
     * check statement
     */

    if ( !__validate_stmt( statement ))
    {
        dm_log_write( __FILE__, 
                    __LINE__, 
                    LOG_INFO, 
                    LOG_INFO, 
                    "Error: SQL_INVALID_HANDLE" );

#ifdef WITH_HANDLE_REDIRECT
		{
			DMHSTMT parent_statement;

			parent_statement = find_parent_handle( statement, SQL_HANDLE_STMT );

			if ( parent_statement ) {
        		dm_log_write( __FILE__, 
                	__LINE__, 
                    	LOG_INFO, 
                    	LOG_INFO, 
                    	"Info: found parent handle" );

				if ( CHECK_SQLEXECDIRECTW( parent_statement -> connection ))
				{
        			dm_log_write( __FILE__, 
                		__LINE__, 
                   		 	LOG_INFO, 
                   		 	LOG_INFO, 
                   		 	"Info: calling redirected driver function" );

                	return  SQLEXECDIRECTW( parent_statement -> connection,
							statement,
							statement_text,
							text_length );
				}
			}
		}
#endif
        return SQL_INVALID_HANDLE;
    }

    function_entry( statement );

    if ( log_info.log_flag )
    {
        /*
         * allocate some space for the buffer
         */

        if ( statement_text && text_length == SQL_NTS )
        {
             s1 = malloc( wide_strlen( statement_text ) * 2 + LOG_MESSAGE_LEN * 2 );
        }
        else if ( statement_text )
        {
            s1 = malloc( text_length + LOG_MESSAGE_LEN * 2 );
        }
        else
        {
            s1 = malloc( LOG_MESSAGE_LEN * 2 );
        }

        sprintf( statement -> msg, "\n\t\tEntry:\
\n\t\t\tStatement = %p\
\n\t\t\tSQL = %s",
                statement,
                __wstring_with_length( s1, statement_text, text_length ));

        free( s1 );

        dm_log_write( __FILE__, 
                __LINE__, 
                LOG_INFO, 
                LOG_INFO, 
                statement -> msg );
    }

    thread_protect( SQL_HANDLE_STMT, statement );

    if ( !statement_text )
    {
        dm_log_write( __FILE__, 
                __LINE__, 
                LOG_INFO, 
                LOG_INFO, 
                "Error: HY009" );

        __post_internal_error( &statement -> error,
                ERROR_HY009, NULL,
                statement -> connection -> environment -> requested_version );

        return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
    }

    if ( text_length <= 0 && text_length != SQL_NTS )
    {
        dm_log_write( __FILE__, 
                __LINE__, 
                LOG_INFO, 
                LOG_INFO, 
                "Error: HY090" );

        __post_internal_error( &statement -> error,
                ERROR_HY090, NULL,
                statement -> connection -> environment -> requested_version );

        return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
    }

    /*
     * check states
     */

#ifdef NR_PROBE
    if ( statement -> state == STATE_S5 ||
            statement -> state == STATE_S6 ||
            statement -> state == STATE_S7 )
#else
    if (( statement -> state == STATE_S6 && statement -> eod == 0 ) ||
            statement -> state == STATE_S7 )
#endif
    {
        dm_log_write( __FILE__, 
                __LINE__, 
                LOG_INFO, 
                LOG_INFO, 
                "Error: 24000" );

        __post_internal_error( &statement -> error,
                ERROR_24000, NULL,
                statement -> connection -> environment -> requested_version );

        return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
    }
    else if ( statement -> state == STATE_S8 ||
            statement -> state == STATE_S9 ||
            statement -> state == STATE_S10 )
    {
        dm_log_write( __FILE__, 
                __LINE__, 
                LOG_INFO, 
                LOG_INFO, 
                "Error: HY010" );

        __post_internal_error( &statement -> error,
                ERROR_HY010, NULL,
                statement -> connection -> environment -> requested_version );

        return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
    }

    if ( statement -> state == STATE_S11 ||
            statement -> state == STATE_S12 )
    {
        if ( statement -> interupted_func != SQL_API_SQLEXECDIRECT )
        {
            dm_log_write( __FILE__, 
                    __LINE__, 
                    LOG_INFO, 
                    LOG_INFO, 
                    "Error: HY010" );

            __post_internal_error( &statement -> error,
                    ERROR_HY010, NULL,
                    statement -> connection -> environment -> requested_version );

            return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
        }
    }

    if ( statement -> connection -> unicode_driver ||
		    CHECK_SQLEXECDIRECTW( statement -> connection ))
    {
#ifdef NR_PROBE
        if ( !CHECK_SQLEXECDIRECTW( statement -> connection ) ||
                !CHECK_SQLNUMRESULTCOLS( statement -> connection ))
        {
            dm_log_write( __FILE__, 
                    __LINE__, 
                    LOG_INFO, 
                    LOG_INFO, 
                    "Error: IM001" );

            __post_internal_error( &statement -> error,
                    ERROR_IM001, NULL,
                    statement -> connection -> environment -> requested_version );

            return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
        }
#else
        if ( !CHECK_SQLEXECDIRECTW( statement -> connection ))
        {
            dm_log_write( __FILE__, 
                    __LINE__, 
                    LOG_INFO, 
                    LOG_INFO, 
                    "Error: IM001" );

            __post_internal_error( &statement -> error,
                    ERROR_IM001, NULL,
                    statement -> connection -> environment -> requested_version );

            return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
        }
#endif

        ret = SQLEXECDIRECTW( statement -> connection,
                statement -> driver_stmt,
                statement_text,
                text_length );
    }
    else
    {
        SQLCHAR *as1 = NULL;
        int clen;

#ifdef NR_PROBE
        if ( !CHECK_SQLEXECDIRECT( statement -> connection ) ||
                !CHECK_SQLNUMRESULTCOLS( statement -> connection ))
        {
            dm_log_write( __FILE__, 
                    __LINE__, 
                    LOG_INFO, 
                    LOG_INFO, 
                    "Error: IM001" );

            __post_internal_error( &statement -> error,
                    ERROR_IM001, NULL,
                    statement -> connection -> environment -> requested_version );

            return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
        }
#else
        if ( !CHECK_SQLEXECDIRECT( statement -> connection ))
        {
            dm_log_write( __FILE__, 
                    __LINE__, 
                    LOG_INFO, 
                    LOG_INFO, 
                    "Error: IM001" );

            __post_internal_error( &statement -> error,
                    ERROR_IM001, NULL,
                    statement -> connection -> environment -> requested_version );

            return function_return( SQL_HANDLE_STMT, statement, SQL_ERROR );
        }
#endif

        as1 = (SQLCHAR*) unicode_to_ansi_alloc( statement_text, text_length, statement -> connection, &clen );

        text_length = clen;

        ret = SQLEXECDIRECT( statement -> connection,
                statement -> driver_stmt,
                as1,
                text_length );

        if ( as1 )
            free( as1 );
    }

    if ( SQL_SUCCEEDED( ret ))
    {
#ifdef NR_PROBE
        SQLRETURN local_ret;
  
        /*
         * grab any errors
         */

        if ( ret == SQL_SUCCESS_WITH_INFO )
        {
            function_return_ex( IGNORE_THREAD, statement, ret, TRUE );
        }

        local_ret = SQLNUMRESULTCOLS( statement -> connection,
                statement -> driver_stmt, &statement -> numcols );

        if ( statement -> numcols > 0 )
        {
            statement -> state = STATE_S5;
        }
        else
        {
            statement -> state = STATE_S4;
        }
#else
        /*
         * We don't know for sure
         */
        statement -> hascols = 1;
        statement -> state = STATE_S5;
#endif

        statement -> prepared = 0;

        /*
         * there is a issue here with transactions, but for the
         * moment
         *
        statement -> connection -> state = STATE_C6;
         */
    }
    else if ( ret == SQL_NEED_DATA )
    {
        statement -> interupted_func = SQL_API_SQLEXECDIRECT;
        statement -> interupted_state = statement -> state;
        statement -> state = STATE_S8;

        statement -> prepared = 0;
    }
    else if ( ret == SQL_PARAM_DATA_AVAILABLE )
    {
        statement -> interupted_func = SQL_API_SQLEXECDIRECT;
        statement -> interupted_state = statement -> state;
        statement -> state = STATE_S13;
    }
    else if ( ret == SQL_STILL_EXECUTING )
    {
        statement -> interupted_func = SQL_API_SQLEXECDIRECT;
        if ( statement -> state != STATE_S11 &&
                statement -> state != STATE_S12 )
            statement -> state = STATE_S11;

        statement -> prepared = 0;
    }
    else
    {
        statement -> state = STATE_S1;
    }

    if ( log_info.log_flag )
    {
        sprintf( statement -> msg, 
                "\n\t\tExit:[%s]",
                    __get_return_status( ret, s2 ));

        dm_log_write( __FILE__, 
                __LINE__, 
                LOG_INFO, 
                LOG_INFO, 
                statement -> msg );
    }

    return function_return( SQL_HANDLE_STMT, statement, ret );
}
Beispiel #26
0
 std::string get_dbms_version() {
   if(SQL_SUCCEEDED(m_dbms_info_available))
     return std::string((char *)m_dbms_ver);
   return std::string("");
 }
Beispiel #27
0
static SQLRETURN
MNDBBrowseConnect(ODBCDbc *dbc,
		  SQLCHAR *InConnectionString,
		  SQLSMALLINT StringLength1,
		  SQLCHAR *OutConnectionString,
		  SQLSMALLINT BufferLength,
		  SQLSMALLINT *StringLength2Ptr)
{
	char *key, *attr;
	char *dsn, *uid, *pwd, *host, *dbname;
	int port;
	SQLSMALLINT len = 0;
	char buf[256];
	int n;
	SQLRETURN rc;
#ifdef ODBCDEBUG
	int allocated = 0;
#endif

	fixODBCstring(InConnectionString, StringLength1, SQLSMALLINT, addDbcError, dbc, return SQL_ERROR);

#ifdef ODBCDEBUG
	ODBCLOG(" \"%.*s\"\n", (int) StringLength1, (char*) InConnectionString);
#endif

	/* check connection state, should not be connected */
	if (dbc->Connected) {
		/* Connection name in use */
		addDbcError(dbc, "08002", NULL, 0);
		return SQL_ERROR;
	}

	dsn = dbc->dsn ? strdup(dbc->dsn) : NULL;
	uid = dbc->uid ? strdup(dbc->uid) : NULL;
	pwd = dbc->pwd ? strdup(dbc->pwd) : NULL;
	host = dbc->host ? strdup(dbc->host) : NULL;
	port = dbc->port;
	dbname = dbc->dbname ? strdup(dbc->dbname) : NULL;

	while ((n = ODBCGetKeyAttr(&InConnectionString, &StringLength1, &key, &attr)) > 0) {
		if (strcasecmp(key, "dsn") == 0 && dsn == NULL) {
			if (dsn)
				free(dsn);
			dsn = attr;
		} else if (strcasecmp(key, "uid") == 0 && uid == NULL) {
			if (uid)
				free(uid);
			uid = attr;
		} else if (strcasecmp(key, "pwd") == 0 && pwd == NULL) {
			if (pwd)
				free(pwd);
			pwd = attr;
		} else if (strcasecmp(key, "host") == 0 && host == NULL) {
			if (host)
				free(host);
			host = attr;
		} else if (strcasecmp(key, "port") == 0 && port == 0) {
			port = atoi(attr);
			free(attr);
		} else if (strcasecmp(key, "database") == 0 && dbname == NULL) {
			if (dbname)
				free(dbname);
			dbname = attr;
#ifdef ODBCDEBUG
		} else if (strcasecmp(key, "logfile") == 0 &&
			   getenv("ODBCDEBUG") == NULL) {
			/* environment trumps everything */
			if (ODBCdebug)
				free((void *) ODBCdebug); /* discard const */
			ODBCdebug = attr;
			allocated = 1;
#endif
		} else
			free(attr);
		free(key);
	}
	if (n < 0)
		goto nomem;

	if (dsn) {
		if (uid == NULL) {
			n = SQLGetPrivateProfileString(dsn, "uid", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				uid = strdup(buf);
				if (uid == NULL)
					goto nomem;
			}
		}
		if (pwd == NULL) {
			n = SQLGetPrivateProfileString(dsn, "pwd", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				pwd = strdup(buf);
				if (pwd == NULL)
					goto nomem;
			}
		}
		if (host == NULL) {
			n = SQLGetPrivateProfileString(dsn, "host", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				host = strdup(buf);
				if (host == NULL)
					goto nomem;
			}
		}
		if (port == 0) {
			n = SQLGetPrivateProfileString(dsn, "port", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				port = atoi(buf);
			}
		}
		if (dbname == NULL) {
			n = SQLGetPrivateProfileString(dsn, "database", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0]) {
				dbname = strdup(buf);
				if (dbname == NULL)
					goto nomem;
			}
		}
#ifdef ODBCDEBUG
		if (!allocated && getenv("ODBCDEBUG") == NULL) {
			/* if not set from InConnectionString argument
			 * or environment, look in profile */
			n = SQLGetPrivateProfileString(dsn, "logfile", "", buf, sizeof(buf), "odbc.ini");
			if (n > 0 && buf[0])
				ODBCdebug = strdup(buf);
		}
#endif
	}

	if (uid != NULL && pwd != NULL) {
		rc = MNDBConnect(dbc, (SQLCHAR *) dsn, SQL_NTS, (SQLCHAR *) uid, SQL_NTS, (SQLCHAR *) pwd, SQL_NTS, host, port, dbname);
		if (SQL_SUCCEEDED(rc)) {
			rc = ODBCConnectionString(rc, dbc, OutConnectionString,
						  BufferLength,
						  StringLength2Ptr,
						  dsn, uid, pwd, host, port,
						  dbname);
		}
	} else {
		if (uid == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "UID:Login ID=?;", BufferLength);
			len += 15;
			OutConnectionString += 15;
			BufferLength -= 15;
		}
		if (pwd == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "PWD:Password=?;", BufferLength);
			len += 15;
			OutConnectionString += 15;
			BufferLength -= 15;
		}
		if (host == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*HOST:Server=?;", BufferLength);
			len += 15;
			OutConnectionString += 15;
			BufferLength -= 15;
		}
		if (port == 0) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*PORT:Port=?;", BufferLength);
			len += 13;
			OutConnectionString += 13;
			BufferLength -= 13;
		}
		if (dbname == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*DATABASE:Database=?;", BufferLength);
			len += 21;
			OutConnectionString += 21;
			BufferLength -= 21;
		}
#ifdef ODBCDEBUG
		if (ODBCdebug == NULL) {
			if (BufferLength > 0)
				strncpy((char *) OutConnectionString, "*LOGFILE:Debug log file=?;", BufferLength);
			len += 26;
			OutConnectionString += 26;
			BufferLength -= 26;
		}
#endif

		if (StringLength2Ptr)
			*StringLength2Ptr = len;

		rc = SQL_NEED_DATA;
	}

  bailout:
	if (dsn)
		free(dsn);
	if (uid)
		free(uid);
	if (pwd)
		free(pwd);
	if (host)
		free(host);
	if (dbname)
		free(dbname);
	return rc;

  nomem:
	/* Memory allocation error */
	addDbcError(dbc, "HY001", NULL, 0);
	rc = SQL_ERROR;
	goto bailout;
}
Beispiel #28
0
static PyObject* CnxnInfo_New(Connection* cnxn)
{
#ifdef _MSC_VER
#pragma warning(disable : 4365)
#endif
    CnxnInfo* p = PyObject_NEW(CnxnInfo, &CnxnInfoType);
    if (!p)
        return 0;
    Object info((PyObject*)p);

    // set defaults
    p->odbc_major             = 3;
    p->odbc_minor             = 50;
    p->supports_describeparam = false;
    p->datetime_precision     = 19; // default: "yyyy-mm-dd hh:mm:ss"
    p->need_long_data_len     = false;

    // WARNING: The GIL lock is released for the *entire* function here.  Do not touch any objects, call Python APIs,
    // etc.  We are simply making ODBC calls and setting atomic values (ints & chars).  Also, make sure the lock gets
    // released -- do not add an early exit.

    SQLRETURN ret;
    Py_BEGIN_ALLOW_THREADS

    char szVer[20];
    SQLSMALLINT cch = 0;
    ret = SQLGetInfo(cnxn->hdbc, SQL_DRIVER_ODBC_VER, szVer, _countof(szVer), &cch);
    if (SQL_SUCCEEDED(ret))
    {
        char* dot = strchr(szVer, '.');
        if (dot)
        {
            *dot = '\0';
            p->odbc_major=(char)atoi(szVer);
            p->odbc_minor=(char)atoi(dot + 1);
        }
    }

    char szYN[2];
    if (SQL_SUCCEEDED(SQLGetInfo(cnxn->hdbc, SQL_DESCRIBE_PARAMETER, szYN, _countof(szYN), &cch)))
        p->supports_describeparam = szYN[0] == 'Y';

    if (SQL_SUCCEEDED(SQLGetInfo(cnxn->hdbc, SQL_NEED_LONG_DATA_LEN, szYN, _countof(szYN), &cch)))
        p->need_long_data_len = (szYN[0] == 'Y');

    // These defaults are tiny, but are necessary for Access.
    p->varchar_maxlength = 255;
    p->wvarchar_maxlength = 255;
    p->binary_maxlength  = 510;

    HSTMT hstmt = 0;
    if (SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, cnxn->hdbc, &hstmt)))
    {
        SQLINTEGER columnsize;
        if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_TYPE_TIMESTAMP)) && SQL_SUCCEEDED(SQLFetch(hstmt)))
            if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0)))
                p->datetime_precision = (int)columnsize;

        if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_VARCHAR)) && SQL_SUCCEEDED(SQLFetch(hstmt)))
            if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0)))
                p->varchar_maxlength = (int)columnsize;

        if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_WVARCHAR)) && SQL_SUCCEEDED(SQLFetch(hstmt)))
            if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0)))
                p->wvarchar_maxlength = (int)columnsize;

        if (SQL_SUCCEEDED(SQLGetTypeInfo(hstmt, SQL_BINARY)) && SQL_SUCCEEDED(SQLFetch(hstmt)))
            if (SQL_SUCCEEDED(SQLGetData(hstmt, 3, SQL_INTEGER, &columnsize, sizeof(columnsize), 0)))
                p->binary_maxlength = (int)columnsize;

        SQLFreeStmt(hstmt, SQL_CLOSE);
    }

    Py_END_ALLOW_THREADS

    // WARNING: Released the lock now.

    return info.Detach();
}
int
main(int argc, char *argv[])
{
	SQLINTEGER cbInString = SQL_NTS;
	char buf[256];
	SQLRETURN ret;
	unsigned char sqlstate[6];

	Connect();

	Command(Statement, "CREATE TABLE #urls ( recdate DATETIME ) ");

	/* test implicit conversion error */
	if (CommandWithResult(Statement, "INSERT INTO #urls ( recdate ) VALUES ( '2003-10-1 10:11:1 0' )") != SQL_ERROR) {
		fprintf(stderr, "SQLExecDirect success instead of failing!\n");
		return 1;
	}

	/* test prepared implicit conversion error */
	if (!SQL_SUCCEEDED(SQLPrepare(Statement, (SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( ? )", SQL_NTS))) {
		fprintf(stderr, "SQLPrepare failure!\n");
		return 1;
	}

	strcpy(buf, "2003-10-1 10:11:1 0");
	if (!SQL_SUCCEEDED
	    (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 128, 0, buf, sizeof(buf), &cbInString))) {
		fprintf(stderr, "SQLBindParameter failure!\n");
		return 1;
	}

	if (SQLExecute(Statement) != SQL_ERROR) {
		fprintf(stderr, "SQLExecute succeeded instead of failing! (line %d)\n", __LINE__);
		return 1;
	}

	ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, buf, sizeof(buf), NULL);
	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
		fprintf(stderr, "Error not set (line %d)\n", __LINE__);
		return 1;
	}
	printf("err=%s\n", buf);

	/* try to prepare and execute a statement with error (from DBD::ODBC test) */
	SQLPrepare(Statement, (SQLCHAR *) "SELECT XXNOTCOLUMN FROM sysobjects", SQL_NTS);

	if (SQLExecute(Statement) != SQL_ERROR) {
		fprintf(stderr, "SQLExecute succeeded instead of failing! (line %d)\n", __LINE__);
		return 1;
	}

	ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, buf, sizeof(buf), NULL);
	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
		fprintf(stderr, "Error not set (line %d) ret=%d\n", __LINE__, (int)ret);
		return 1;
	}
	printf("err=%s\n", buf);


	Disconnect();

	printf("Done.\n");
	return 0;
}
Beispiel #30
0
static SQLRETURN extract_sql_error_field( EHEAD *head,
                SQLSMALLINT rec_number,
                SQLSMALLINT diag_identifier,
                SQLPOINTER diag_info_ptr,
                SQLSMALLINT buffer_length,
                SQLSMALLINT *string_length_ptr )
{
    ERROR *ptr;

    /*
     * check the header fields first
     */

    switch( diag_identifier )
    {
      case SQL_DIAG_CURSOR_ROW_COUNT:
      case SQL_DIAG_ROW_COUNT:
        {
            SQLLEN val;
            SQLRETURN ret;

            if ( head -> handle_type != SQL_HANDLE_STMT )
            {
                return SQL_ERROR;
            }
            else if ( head -> header_set )
            {
                switch( diag_identifier )
                {
                  case SQL_DIAG_CURSOR_ROW_COUNT:
                    if ( SQL_SUCCEEDED( head -> diag_cursor_row_count_ret ) && diag_info_ptr )
                    {
                        *((SQLLEN*)diag_info_ptr) = head -> diag_cursor_row_count;
                    }
                    return head -> diag_cursor_row_count_ret;

                  case SQL_DIAG_ROW_COUNT:
                    if ( SQL_SUCCEEDED( head -> diag_row_count_ret ) && diag_info_ptr )
                    {
                        *((SQLLEN*)diag_info_ptr) = head -> diag_row_count;
                    }
                    return head -> diag_row_count_ret;
                }
            }
            else if ( __get_connection( head ) -> unicode_driver &&
                CHECK_SQLGETDIAGFIELDW( __get_connection( head )))
            {
                ret = SQLGETDIAGFIELDW( __get_connection( head ),
                        SQL_HANDLE_STMT,
                        __get_driver_handle( head ),
                        0,
                        diag_identifier,
                        diag_info_ptr,
                        buffer_length,
                        string_length_ptr );

                return ret;
            }
            else if ( !__get_connection( head ) -> unicode_driver &&
                CHECK_SQLGETDIAGFIELD( __get_connection( head )))
            {
                ret = SQLGETDIAGFIELD( __get_connection( head ),
                        SQL_HANDLE_STMT,
                        __get_driver_handle( head ),
                        0,
                        diag_identifier,
                        diag_info_ptr,
                        buffer_length,
                        string_length_ptr );

                return ret;
            }
            else if ( CHECK_SQLROWCOUNT( __get_connection( head )))
            {
                ret = DEF_SQLROWCOUNT( __get_connection( head ),
                    __get_driver_handle( head ),
                    &val );

                if ( !SQL_SUCCEEDED( ret ))
                {
                    return ret;
                }
            }
            else
            {
                val = 0;
            }

            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &val, sizeof( val ));
            }
        }
        return SQL_SUCCESS;

      case SQL_DIAG_DYNAMIC_FUNCTION:
        {
            SQLRETURN ret;

            if ( head -> handle_type != SQL_HANDLE_STMT )
            {
                return SQL_ERROR;
            }
            else if ( head -> header_set )
            {
                if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret ) && diag_info_ptr )
                {
                    unicode_to_ansi_copy( diag_info_ptr, buffer_length, head -> diag_dynamic_function, buffer_length, __get_connection( head ));
                    if ( string_length_ptr )
                    {
                        *string_length_ptr = wide_strlen( head -> diag_dynamic_function );
                    }
                }
                return head -> diag_dynamic_function_ret;
            }
            else if ( __get_connection( head ) -> unicode_driver &&
                CHECK_SQLGETDIAGFIELDW( __get_connection( head )))
            {
                SQLWCHAR *s1;

                if ( buffer_length > 0 )
                {
                    s1 = malloc( sizeof( SQLWCHAR ) * ( buffer_length + 1 ));
                }
                
                ret = SQLGETDIAGFIELDW( __get_connection( head ),
                        SQL_HANDLE_STMT,
                        __get_driver_handle( head ),
                        0,
                        diag_identifier,
                        s1 ? s1 : diag_info_ptr,
                        buffer_length,
                        string_length_ptr );

                if ( SQL_SUCCEEDED( ret ) && diag_info_ptr && s1 )
                {
                    unicode_to_ansi_copy( diag_info_ptr, buffer_length, s1, buffer_length, __get_connection( head ));
                }

                if ( s1 )
                {
                    free( s1 );
                }

                return ret;
            }
            else if ( !__get_connection( head ) -> unicode_driver &&
                CHECK_SQLGETDIAGFIELD( __get_connection( head )))
            {
                ret = SQLGETDIAGFIELD( __get_connection( head ),
                        SQL_HANDLE_STMT,
                        __get_driver_handle( head ),
                        0,
                        diag_identifier,
                        diag_info_ptr,
                        buffer_length,
                        string_length_ptr );

                return ret;
            }
            if ( diag_info_ptr )
            {
                strcpy( diag_info_ptr, "" );
            }
        }
        return SQL_SUCCESS;

      case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
        {
            SQLINTEGER val;
            SQLRETURN ret;

            if ( head -> handle_type != SQL_HANDLE_STMT )
            {
                return SQL_ERROR;
            }
            else if ( head -> header_set )
            {
                if ( SQL_SUCCEEDED( head -> diag_dynamic_function_code_ret ) && diag_info_ptr )
                {
                    *((SQLINTEGER*)diag_info_ptr) = head -> diag_dynamic_function_code;
                }
                return head -> diag_dynamic_function_code_ret;
            }
            else if ( __get_connection( head ) -> unicode_driver &&
                CHECK_SQLGETDIAGFIELDW( __get_connection( head )))
            {
                ret = SQLGETDIAGFIELDW( __get_connection( head ),
                        SQL_HANDLE_STMT,
                        __get_driver_handle( head ),
                        0,
                        diag_identifier,
                        diag_info_ptr,
                        buffer_length,
                        string_length_ptr );

                return ret;
            }
            else if ( !__get_connection( head ) -> unicode_driver &&
                CHECK_SQLGETDIAGFIELD( __get_connection( head )))
            {
                ret = SQLGETDIAGFIELD( __get_connection( head ),
                        SQL_HANDLE_STMT,
                        __get_driver_handle( head ),
                        0,
                        diag_identifier,
                        diag_info_ptr,
                        buffer_length,
                        string_length_ptr );

                return ret;
            }
            else
            {
                val = SQL_DIAG_UNKNOWN_STATEMENT;
            }

            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &val, sizeof( val ));
            }
        }
        return SQL_SUCCESS;

      case SQL_DIAG_NUMBER:
        {
            SQLINTEGER val;
            
            val = head -> sql_diag_head.internal_count + 
                head -> sql_diag_head.error_count;

            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &val, sizeof( val ));
            }
        }
        return SQL_SUCCESS;

      case SQL_DIAG_RETURNCODE:
        {
            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &head -> return_code, 
                        sizeof( head -> return_code ));
            }
        }
        return SQL_SUCCESS;
    }

    /*
     * else check the records
     */

    if ( rec_number < 1 )
    {
        return SQL_ERROR;
    }

    if ( rec_number <= head -> sql_diag_head.internal_count )
    {
        /*
         * local errors
         */

        ptr = head -> sql_diag_head.internal_list_head;
        while( rec_number > 1 )
        {
            ptr = ptr -> next;
            rec_number --;
        }
    }
    else if ( !__is_env( head ) && __get_connection( head ) -> state != STATE_C2 )
    {
		rec_number -= head -> sql_diag_head.internal_count;

        if ( __get_connection( head ) -> unicode_driver &&
            CHECK_SQLGETDIAGFIELDW( __get_connection( head )))
        {
            SQLRETURN ret;
            SQLWCHAR *s1 = NULL;
			int char_buffer_len = sizeof( SQLWCHAR ) * buffer_length;

            if ( buffer_length > 0 )
            {
                s1 = malloc( char_buffer_len + sizeof( SQLWCHAR ));
            }

            ret = SQLGETDIAGFIELDW( __get_connection( head ),
                    head -> handle_type,
                    __get_driver_handle( head ),
                    rec_number,
                    diag_identifier,
                    s1 ? s1 : diag_info_ptr,
                    char_buffer_len,
                    string_length_ptr );

            if ( SQL_SUCCEEDED( ret ) && s1 && diag_info_ptr )
            {
                unicode_to_ansi_copy( diag_info_ptr, buffer_length, s1, SQL_NTS, __get_connection( head ));
            }

            if ( s1 )
            {
                free( s1 );
            }

			if ( string_length_ptr && *string_length_ptr > 0 ) 
			{
				*string_length_ptr /= sizeof( SQLWCHAR );
			}

            if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE )
            {
                /*
                 * map 3 to 2 if required
                 */
                if ( diag_info_ptr )
                {
                    if ( diag_info_ptr )
                        __map_error_state( diag_info_ptr, __get_version( head ));
                }
            }

            return ret;
        }
		else if ( !__get_connection( head ) -> unicode_driver &&
            CHECK_SQLGETDIAGFIELD( __get_connection( head )))
        {
            SQLRETURN ret;

            ret = SQLGETDIAGFIELD( __get_connection( head ),
                    head -> handle_type,
                    __get_driver_handle( head ),
                    rec_number,
                    diag_identifier,
                    diag_info_ptr,
                    buffer_length,
                    string_length_ptr );

            if ( SQL_SUCCEEDED( ret ) && diag_identifier == SQL_DIAG_SQLSTATE )
            {
                /*
                 * map 3 to 2 if required
                 */
                if ( diag_info_ptr )
                {
                    if ( diag_info_ptr )
                        __map_error_state( diag_info_ptr, __get_version( head ));
                }
            }

            return ret;
        }
        else
        {
            ptr = head -> sql_diag_head.error_list_head;
            while( rec_number > 1 )
            {
                ptr = ptr -> next;
                rec_number --;
            }
        }
    }
    else 
    {
	    return SQL_NO_DATA;
    }

    /*
     * if we are here ptr should point to the local error
     * record
     */

    switch( diag_identifier )
    {
      case SQL_DIAG_CLASS_ORIGIN:
        {
            if ( SQL_SUCCEEDED( ptr -> diag_class_origin_ret ))
            {
                unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_class_origin, buffer_length, __get_connection( head ));
                if ( string_length_ptr )
                {
                    *string_length_ptr = wide_strlen( ptr -> diag_class_origin );
                }
                return ptr -> diag_class_origin_ret;
            }
            else
            {
                return ptr -> diag_class_origin_ret;
            }
        }
        break;

      case SQL_DIAG_COLUMN_NUMBER:
        {
            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &ptr -> diag_column_number, sizeof( SQLINTEGER ));
            }
            return SQL_SUCCESS;
        }
        break;

      case SQL_DIAG_CONNECTION_NAME:
        {
            if ( SQL_SUCCEEDED( ptr -> diag_connection_name_ret ))
            {
                unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_connection_name, buffer_length, __get_connection( head ));
                if ( string_length_ptr )
                {
                    *string_length_ptr = wide_strlen( ptr -> diag_connection_name );
                }
                return ptr -> diag_connection_name_ret;
            }
            else
            {
                return ptr -> diag_connection_name_ret;
            }
        }
        break;

      case SQL_DIAG_MESSAGE_TEXT:
        {
            char *str;
            int ret = SQL_SUCCESS;

            str = unicode_to_ansi_alloc( ptr -> msg, SQL_NTS, __get_connection( head ));

            if ( diag_info_ptr )
            {
                if ( buffer_length >= strlen( str ) + 1 )
                {
                    strcpy( diag_info_ptr, str );
                }
                else
                {
                    ret = SQL_SUCCESS_WITH_INFO;
                    memcpy( diag_info_ptr, str, buffer_length - 1 );
                    (( char * ) diag_info_ptr )[ buffer_length - 1 ] = '\0';
                }
            }
            if ( string_length_ptr )
            {
                *string_length_ptr = strlen( str );
            }

            if ( str )
            {
                free( str );
            }

            return ret;
        }
        break;

      case SQL_DIAG_NATIVE:
        {
            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &ptr -> native_error, sizeof( SQLINTEGER ));
            }
            return SQL_SUCCESS;
        }
        break;

      case SQL_DIAG_ROW_NUMBER:
        {
            if ( diag_info_ptr )
            {
                memcpy( diag_info_ptr, &ptr -> diag_row_number, sizeof( SQLLEN ));
            }
            return SQL_SUCCESS;
        }
        break;

      case SQL_DIAG_SERVER_NAME:
        {
            if ( SQL_SUCCEEDED( ptr -> diag_server_name_ret ))
            {
                unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_server_name, buffer_length, __get_connection( head ));
                if ( string_length_ptr )
                {
                    *string_length_ptr = wide_strlen( ptr -> diag_server_name );
                }
                return ptr -> diag_server_name_ret;
            }
            else
            {
                return ptr -> diag_server_name_ret;
            }
        }
        break;

      case SQL_DIAG_SQLSTATE:
        {
            char *str;
            int ret = SQL_SUCCESS;

            str = unicode_to_ansi_alloc( ptr -> sqlstate, SQL_NTS, __get_connection( head ));

            if ( diag_info_ptr )
            {
                if ( buffer_length >= strlen( str ) + 1 )
                {
                    strcpy( diag_info_ptr, str );
                }
                else
                {
                    ret = SQL_SUCCESS_WITH_INFO;
                    memcpy( diag_info_ptr, str, buffer_length - 1 );
                    (( char * ) diag_info_ptr )[ buffer_length - 1 ] = '\0';
                }

                /*
                 * map 3 to 2 if required
                 */

                if ( diag_info_ptr )
                    __map_error_state( diag_info_ptr, __get_version( head ));
            }
            if ( string_length_ptr )
            {
                *string_length_ptr = strlen( str );
            }

            if ( str )
            {
                free( str );
            }

            return ret;
        }
        break;

      case SQL_DIAG_SUBCLASS_ORIGIN:
        {
            if ( SQL_SUCCEEDED( ptr -> diag_subclass_origin_ret ))
            {
                unicode_to_ansi_copy( diag_info_ptr, buffer_length, ptr -> diag_subclass_origin, buffer_length, __get_connection( head ));
                if ( string_length_ptr )
                {
                    *string_length_ptr = wide_strlen( ptr -> diag_subclass_origin );
                }
                return ptr -> diag_subclass_origin_ret;
            }
            else
            {
                return ptr -> diag_subclass_origin_ret;
            }
        }
        break;
    }

    return SQL_SUCCESS;
}