Bcp_init返回访问冲突
bcp_init rturns access violation
我试图在c++中使用odbc在sql server中进行批量复制。下面是我的代码:
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <odbcss.h>
#include<tchar.h>
SQLHENV henv = SQL_NULL_HENV;
HDBC hdbc1 = SQL_NULL_HDBC, hdbc2 = SQL_NULL_HDBC;
SQLHSTMT hstmt2 = SQL_NULL_HSTMT;
void Cleanup() {
if (hstmt2 != SQL_NULL_HSTMT)
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
if (hdbc1 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
}
if (hdbc2 != SQL_NULL_HDBC) {
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
}
if (henv != SQL_NULL_HENV)
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
void HandleDiagnosticRecord (SQLHANDLE hHandle,
SQLSMALLINT hType,
RETCODE RetCode)
{
SQLSMALLINT iRec = 0;
SQLINTEGER iError;
WCHAR wszMessage[1000];
WCHAR wszState[SQL_SQLSTATE_SIZE+1];
if (RetCode == SQL_INVALID_HANDLE)
{
fwprintf(stderr, L"Invalid handle!n");
return;
}
while (SQLGetDiagRec(hType,
hHandle,
++iRec,
wszState,
&iError,
wszMessage,
(SQLSMALLINT)(sizeof(wszMessage) / sizeof(WCHAR)),
(SQLSMALLINT *)NULL) == SQL_SUCCESS)
{
// Hide data truncated..
if (wcsncmp(wszState, L"01004", 5))
{
fwprintf(stderr, L"[%5.5s] %s (%d)n", wszState, wszMessage, iError);
}
}
}
#define TRYODBC(h, ht, x) { RETCODE rc = x;
if (rc != SQL_SUCCESS)
{
HandleDiagnosticRecord (h, ht, rc);
}
if (rc == SQL_ERROR)
{
fwprintf(stderr, L"Error in " L#x L"n");
Sleep(30000);
}
}
void extract_error(
char *fn,
SQLHANDLE handle,
SQLSMALLINT type)
{
SQLINTEGER i = 0;
SQLINTEGER native;
SQLWCHAR state[ 7 ];
SQLWCHAR text[256];
SQLSMALLINT len;
SQLRETURN ret;
fprintf(stderr,
"n"
"The driver reported the following diagnostics whilst running "
"%snn",
fn);
do
{
ret = SQLGetDiagRec(type, handle, ++i, state, &native, text,
sizeof(text), &len );
if (SQL_SUCCEEDED(ret))
printf("%s:%ld:%ld:%sn", state, i, native, text);
}
while( ret == SQL_SUCCESS );
}
int main() {
RETCODE retcode;
// BCP variables.
char *terminator = " ";
// bcp_done takes a different format return code because it returns number of rows bulk copied
// after the last bcp_batch call.
DBINT cRowsDone = 0;
// Set up separate return code for bcp_sendrow so it is not using the same retcode as SQLFetch.
RETCODE SendRet;
// Allocate the ODBC environment and save handle.
retcode = SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(Env) Failednn");
Cleanup();
return(9);
}
// Notify ODBC that this is an ODBC 3.0 app.
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetEnvAttr(ODBC version) Failednn");
Cleanup();
return(9);
}
// Allocate ODBC connection handle, set bulk copy mode, and connect.
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLAllocHandle(hdbc1) Failednn");
Cleanup();
return(9);
}
retcode = SQLSetConnectAttr(hdbc1, SQL_COPT_SS_BCP, (void *)SQL_BCP_ON, SQL_IS_INTEGER);
if ( (retcode != SQL_SUCCESS_WITH_INFO) && (retcode != SQL_SUCCESS)) {
printf("SQLSetConnectAttr(hdbc1) Failednn");
Cleanup();
return(9);
}
// sample uses Integrated Security, create the SQL Server DSN using Windows NT authentication
SQLWCHAR dsn[30] = L"mssqltest"; //Name DNS
SQLWCHAR user[10] = L"di_test";
SQLWCHAR pass[10] = L"di_test";
SQLWCHAR tb[20]=L"information1";
retcode = SQLConnectW(hdbc1, (SQLWCHAR *)dsn, SQL_NTS, (SQLWCHAR *) user, SQL_NTS, (SQLWCHAR *) pass, SQL_NTS);
if ( (retcode != SQL_SUCCESS) && (retcode != SQL_SUCCESS_WITH_INFO) ) {
printf("SQLConnect() Failednn");
Cleanup();
return(9);
}
// TRYODBC(hdbc1, SQL_HANDLE_DBC, retcode);
// Initialize the bulk copy.
retcode = bcp_init(hdbc1,L"information1", NULL, NULL, DB_IN);
if ( (retcode != SUCCEED) ) {
printf("bcp_init(hdbc1) Failednn");
Cleanup();
return(9);
}
//Define our array
SQLINTEGER custIDs[] = { 1, 2, 3, 4};
// Bind the program variables for the bulk copy.
retcode = bcp_bind(hdbc1, (BYTE *)custIDs[0], 4, SQL_VARLEN_DATA, NULL, (INT)NULL, SQLINT4, 2);
if ( (retcode != SUCCEED) ) {
printf("bcp_bind(hdbc1) Failednn");
Cleanup();
return(9);
}
// Could normally use strlen to calculate the bcp_bind cbTerm parameter, but this terminator
// is a null byte ( ), which gives strlen a value of 0. Explicitly give cbTerm a value of 1.
retcode = bcp_bind(hdbc1, (BYTE *)custIDs[0], 4, SQL_VARLEN_DATA, NULL, (INT)NULL, SQLINT4, 3);
if ( (retcode != SUCCEED) ) {
printf("bcp_bind(hdbc1) Failednn");
Cleanup();
return(9);
}
if ( (SendRet = bcp_sendrow(hdbc1) ) != SUCCEED ) {
printf("bcp_sendrow(hdbc1) Failednn");
Cleanup();
return(9);
}
cRowsDone = bcp_done(hdbc1);
if ( (cRowsDone == -1) ) {
printf("bcp_done(hdbc1) Failednn");
Cleanup();
return(9);
}
printf("Number of rows bulk copied after last bcp_batch call = %d.n", cRowsDone);
// Cleanup.
SQLFreeHandle(SQL_HANDLE_STMT, hstmt2);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLDisconnect(hdbc2);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc2);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
}
retcode = bcp_init(hdbc1,L"information1", NULL, NULL, DB_IN);
我得到一个异常,访问冲突。除了一个异常,我没有收到任何错误。有人知道我该怎么解决这个问题吗? 我已经在一个win32程序中使用bcp_xxxx
函数12-15年了。该程序是在VS6上编译的,目前仍在生产中。
我最近在VS2015上重写了这个项目(终于…)。我和你一样,也有bcp_xxxx
函数的问题。
最初的VS6程序包含以下文件:
#include <sql.h>
#include <sqlext.h>
#include "C:Program FilesMicrosoft SQL Server80ToolsDevToolsIncludeodbcss.h"
SQLDriverConnect()
函数使用包含Driver=SQL Server
的连接字符串。
odbcbcp.lib
被添加到链接器库列表中。没有问题。
该程序已在VS2015中完全重新访问,在适当的时候将ODBC函数更改为其版本3。允许使用UNICODE或ANSI字符集的32位或64位二进制文件。
最近的文档建议在使用bcp_xxxx
函数时使用sqlncli.h
头和sqlncli11.lib
:
#include <sql.h>
#include <sqlext.h>
#define _SQLNCLI_ODBC_
#ifdef _WIN64
#include "C:Program FilesMicrosoft SQL Server110SDKIncludesqlncli.h"
#else
#include "C:Program Files (x86)Microsoft SQL Server110SDKIncludesqlncli.h"
#endif
我按照建议做了,然后…崩溃。
然后我链接回odbcbcp.lib
,它就像一个魅力。
所以,我开始搜索如何使用sqlncli11.lib
,我发现ODBC连接字符串应该包含Driver=SQL Server Native Client 11.0
。
简而言之:
- (1) Driver=SQL Server
与odbcbcp.lib
作品
- (2) Driver=SQL Server
与sqlncli11.lib
使bcp_init()
崩溃
- (3) Driver=SQL Server Native Client 11.0
与odbcbcp.lib
使bcp_init()
失败(它返回FAIL
=0)
- (4) Driver=SQL Server Native Client 11.0
与sqlncli11.lib
作品。
选项(1)和(4)正在工作。
但是我也发现使用option(4)可以让查询运行得更快!
所以我保留最后一个。
- 写入位置0x0000000C时发生访问冲突
- 引发异常:读取访问冲突**dynamicArray**为0x1118235.发生
- 链表中写入访问冲突的未知原因
- C++中的openCV Mat访问冲突
- C++尝试深度复制唯一指针时出现内存访问冲突
- C++ 中动态二维数组的访问冲突
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- 写入访问冲突异常
- 在类 12.exe 中0x7B37FF80 (ucrtbased.dll) 引发异常: 0xC0000005:访问冲突读
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 访问冲突投射到无效*并返回
- 为什么我的布尔函数返回 true 会导致读取访问冲突?
- 从C#返回调用C++dll函数的值时发生访问冲突
- c++抛出0xC0000005:写入位置0xFEEEFEEE的访问冲突.从main返回时
- 返回指针会扰乱对象(访问冲突)
- c++返回元素在没有代码的行上给出访问冲突
- 当函数在fread()应用于局部结构变量后返回时发生访问冲突
- Bcp_init返回访问冲突
- c++ Vector读访问冲突Mylast返回0x8
- 尝试返回同一类中的私有变量时C++ "Getter"方法抛出访问冲突