2012年3月29日星期四

bcp_init and SQL Native Client

Hi all,
I am having trouble to get the bulk copy operations working in
collaboration with SQL Native Client.
My test program crashed with an access violation in the call to
bcp_init.
I know that the error is probably mine, but I cannot find any
mistakes.
I have include the C++ source below, and I hope that someone can help
me:
#include <windows.h>
#include <oledb.h>
#include <sql.h>
#include <sqlext.h>
#include <sqltypes.h>
#define _SQLNCLI_ODBC_
#include <sqlncli.h>
#include <cassert>
#include <iostream>
namespace
{
HENV createEnvironment()
{
HENV environment;
SQLRETURN result;
result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
&environment);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
throw std::runtime_error("SQLAllocHandle failed");
}
result = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION,
reinterpret_cast <SQLPOINTER> (SQL_OV_ODBC3), SQL_IS_INTEGER);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
throw std::runtime_error("SQLSetEnvAttr failed");
}
return environment;
}
SQLHDBC createConnection(HENV environment)
{
SQLHDBC connection;
SQLRETURN result;
result = SQLAllocHandle(SQL_HANDLE_DBC, environment, &connection);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
throw std::runtime_error("SQLAllocHandle failed");
}
// Need to set this prior to connection.
result = SQLSetConnectAttr(connection, SQL_COPT_SS_BCP, (void*)
SQL_BCP_ON,
SQL_IS_INTEGER);
result = SQLConnect(connection, reinterpret_cast <SQLCHAR*> (
const_cast <char*> ("database")), SQL_NTS, reinterpret_cast
<SQLCHAR*> (
const_cast <char*> ("user")), SQL_NTS, reinterpret_cast <SQLCHAR*>
(
const_cast <char*> ("password")), SQL_NTS);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
throw std::runtime_error("SQLConnect failed");
}
return connection;
}
int realMain(int argc, char *argv[])
{
HENV environment = createEnvironment();
SQLHDBC connection = createConnection(environment);
RETCODE result;
result = bcp_init(connection, "testdata", 0, 0, DB_IN);
assert(result != FAIL);
return 0;
}
} // anonymous namespace
int main(int argc, char* argv[])
{
try
{
return realMain(argc, argv);
}
catch (const std::exception& ex)
{
std::cerr << "exception: " << ex.what() << std::endl;
}
return 1;
}There is no error in my side. To enable trobule-shooting, you may add the
following code segment just after bcp_init:
result = bcp_init(connection, "myTable", 0, 0, DB_IN);
char SQLState[6] = "";
char Msg[256] = "";
SQLINTEGER iNativeError = 0;
SQLSMALLINT iMsgLen = 0;
int iRc = SQLGetDiagRec(SQL_HANDLE_DBC, connection, 1,
(SQLCHAR*)SQLState, &iNativeError, (SQLCHAR*)Msg, 256, &iMsgLen);
if (iRc != SQL_NO_DATA) {
printf("SQLState=%s, NativeError=%d, Msg=%s\n", SQLState,
iNativeError, Msg);
}
assert(result != FAIL);
Ming.
MDAC Team, Microsoft.
"Peter" wrote:
> Hi all,
> I am having trouble to get the bulk copy operations working in
> collaboration with SQL Native Client.
> My test program crashed with an access violation in the call to
> bcp_init.
> I know that the error is probably mine, but I cannot find any
> mistakes.
> I have include the C++ source below, and I hope that someone can help
> me:
> #include <windows.h>
> #include <oledb.h>
> #include <sql.h>
> #include <sqlext.h>
> #include <sqltypes.h>
> #define _SQLNCLI_ODBC_
> #include <sqlncli.h>
> #include <cassert>
> #include <iostream>
> namespace
> {
> HENV createEnvironment()
> {
> HENV environment;
> SQLRETURN result;
> result = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE,
> &environment);
> if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
> {
> throw std::runtime_error("SQLAllocHandle failed");
> }
> result = SQLSetEnvAttr(environment, SQL_ATTR_ODBC_VERSION,
> reinterpret_cast <SQLPOINTER> (SQL_OV_ODBC3), SQL_IS_INTEGER);
> if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
> {
> throw std::runtime_error("SQLSetEnvAttr failed");
> }
> return environment;
> }
> SQLHDBC createConnection(HENV environment)
> {
> SQLHDBC connection;
> SQLRETURN result;
> result = SQLAllocHandle(SQL_HANDLE_DBC, environment, &connection);
> if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
> {
> throw std::runtime_error("SQLAllocHandle failed");
> }
> // Need to set this prior to connection.
> result = SQLSetConnectAttr(connection, SQL_COPT_SS_BCP, (void*)
> SQL_BCP_ON,
> SQL_IS_INTEGER);
> result = SQLConnect(connection, reinterpret_cast <SQLCHAR*> (
> const_cast <char*> ("database")), SQL_NTS, reinterpret_cast
> <SQLCHAR*> (
> const_cast <char*> ("user")), SQL_NTS, reinterpret_cast <SQLCHAR*>
> (
> const_cast <char*> ("password")), SQL_NTS);
> if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
> {
> throw std::runtime_error("SQLConnect failed");
> }
> return connection;
> }
> int realMain(int argc, char *argv[])
> {
> HENV environment = createEnvironment();
> SQLHDBC connection = createConnection(environment);
> RETCODE result;
> result = bcp_init(connection, "testdata", 0, 0, DB_IN);
> assert(result != FAIL);
> return 0;
> }
> } // anonymous namespace
> int main(int argc, char* argv[])
> {
> try
> {
> return realMain(argc, argv);
> }
> catch (const std::exception& ex)
> {
> std::cerr << "exception: " << ex.what() << std::endl;
> }
> return 1;
> }
>

没有评论:

发表评论