CDatabase::executeSql 之vc 6.0 与 vs 2008 的区别

博客讲述了作者在使用CDatabase::executeSql执行更新语句时遇到的问题,VS 2008环境下执行无结果集的更新语句会抛出异常,而在VC 6.0环境中则不会。问题根源在于VS 2008的实现方式,解决方案是派生CDatabase并重写ExecuteSQL方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

困恼了一个星期的问题终于解决了。之前,在vs 2008 上用 CDatabase::executeSql("update bp_tmpbatch_tb set progress_flag = 0 where
1 = 0 ")的语句,总是莫名奇妙的抛出异常,"错误的函数序列"。一开始观察执行的sql语句 ,发现sql语句在语法上并没有错,对比在vc 6.0环境
执行的情况,并没有报错,很难理解,于是认为 vs2008上  CDatabase::executeSql()执行updata,delete 都会报错,然后各种百度,各种go
ogle,都找不到答案,各种郁闷。
      今天,经过各种失败后,终于转变思维,发现"update bp_tmpbatch_tb set progress_flag = 0 where 1 = 0 " 这句话 在sql语句上没问题,
但它却没有结果集,所以 vs2008上  CDatabase::executeSql()抛异常了,接着测试了其他另外几条类似的语句,得到相同的异常,但当 CD
atabase::executeSql()执行 "update bp_tmpbatch_tb set progress_flag = 0 where batch_id =  '20110331094619171022' "这种有结果集的
语句时,是不会抛异常的。
       同一条语句,在vc 6.0 与 vs 2008执行有差别,主要在与vc 6.0 的CDatabase::executeSql()和 vs 2008的CDatabase::executeSql()
实现方式不一样,vc 6.0中具体为:

所以,要解决VS2008无记录集不报错,还得自己派生CDatabase,然后重写 void CDatabase::ExecuteSQL(LPCTSTR lpszSQL)啊。

 

 
void CDatabase::ExecuteSQL(LPCTSTR lpszSQL)
{
USES_CONVERSION;
RETCODE nRetCode;
HSTMT hstmt;
ASSERT_VALID(this);
ASSERT(AfxIsValidString(lpszSQL));

AFX_SQL_SYNC(::SQLAllocStmt(m_hdbc, &hstmt));
if (!CheckHstmt(nRetCode, hstmt))
AfxThrowDBException(nRetCode, this, hstmt);


TRY
{
OnSetOptions(hstmt);

// Give derived CDatabase classes option to use parameters
BindParameters(hstmt);

AFX_ODBC_CALL(::SQLExecDirect(hstmt,
(UCHAR*)T2A((LPTSTR)lpszSQL), SQL_NTS));


if (!CheckHstmt(nRetCode, hstmt))
AfxThrowDBException(nRetCode, this, hstmt);
else
{
do
{
SWORD nResultColumns;
AFX_ODBC_CALL(::SQLNumResultCols(hstmt, &nResultColumns));
if (nResultColumns != 0)
{
do
{
AFX_ODBC_CALL(::SQLFetch(hstmt));
} while (CheckHstmt(nRetCode, hstmt) &&
nRetCode != SQL_NO_DATA_FOUND);
}
AFX_ODBC_CALL(::SQLMoreResults(hstmt));
} while (CheckHstmt(nRetCode, hstmt) &&
nRetCode != SQL_NO_DATA_FOUND);
}
}
CATCH_ALL(e)
{
::SQLCancel(hstmt);
AFX_SQL_SYNC(::SQLFreeStmt(hstmt, SQL_DROP));
THROW_LAST();
}
END_CATCH_ALL


AFX_SQL_SYNC(::SQLFreeStmt(hstmt, SQL_DROP));
}

vs 2008 为:

void CDatabase::ExecuteSQL(LPCTSTR lpszSQL)
{
RETCODE nRetCode;
HSTMT hstmt;


ENSURE_VALID(this);
ENSURE_ARG(AfxIsValidString(lpszSQL));


AFX_SQL_SYNC(::SQLAllocStmt(m_hdbc, &hstmt));
if (!CheckHstmt(nRetCode, hstmt))
AfxThrowDBException(nRetCode, this, hstmt);


TRY
{
OnSetOptions(hstmt);
// Give derived CDatabase classes option to use parameters
BindParameters(hstmt);
LPTSTR pszSQL = const_cast<LPTSTR>(lpszSQL);
AFX_ODBC_CALL(::SQLExecDirect(hstmt, reinterpret_cast<SQLTCHAR *>(pszSQL), SQL_NTS));
if (!CheckHstmt(nRetCode, hstmt))
AfxThrowDBException(nRetCode, this, hstmt);

SWORD nResultColumns;
do
{
AFX_ODBC_CALL(::SQLNumResultCols(hstmt, &nResultColumns));
if(!CheckHstmt(nRetCode, hstmt))  //  vs 2008 这里多出一些判断,更加严谨了,无记录集会抛异常。
AfxThrowDBException(nRetCode, this, hstmt);
if (nResultColumns != 0)
do
{
AFX_ODBC_CALL(::SQLFetch(hstmt));
if(!CheckHstmt(nRetCode, hstmt))
AfxThrowDBException(nRetCode, this, hstmt);
} while (nRetCode != SQL_NO_DATA_FOUND);
AFX_ODBC_CALL(::SQLMoreResults(hstmt));
if(!CheckHstmt(nRetCode, hstmt))
AfxThrowDBException(nRetCode, this, hstmt);
} while (nRetCode != SQL_NO_DATA_FOUND);
}
CATCH_ALL(e)
{
::SQLCancel(hstmt);
AFX_SQL_SYNC(::SQLFreeStmt(hstmt, SQL_DROP));
THROW_LAST();
}
END_CATCH_ALL


AFX_SQL_SYNC(::SQLFreeStmt(hstmt, SQL_DROP));
}

所以,要解决VS2008无记录集不报错,还得自己派生CDatabase,然后重写 void CDatabase::ExecuteSQL(LPCTSTR lpszSQL)啊。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值