我有几个查询应该返回多个“受影响的行”(并且在通过SQL Server Management Studio
运行时执行此操作),但我似乎无法弄清楚如何正确调用dbcount
多次
这是我使用FreeTDS library:
的测试功能- (BOOL) testCommand: (NSString*) queryToExecute
{
RETCODE retcode;
// Set our command
retcode = dbcmd(dbProc, [queryToExecute UTF8String]);
if(SUCCEED != retcode)
{
return NO;
} // End of failed to set command
retcode = dbsqlexec(dbProc);
if(SUCCEED != retcode)
{
NSLog(@"Query failure, retcode was: %d", retcode);
// Error handling goes here
return NO;
} // End of failed to sqlexec
while(SUCCEED == (retcode = dbresults(dbProc)))
{
if(SUCCEED == (retcode = dbrows(dbProc)))
{
// Loop though our records
NSUInteger rowCount = 0;
while (NO_MORE_ROWS != (retcode = dbnextrow(dbProc)))
{
++rowCount;
} // End of records loop
NSLog(@"Command completed successfully. (%ld results).", rowCount);
} // End dbrows succeeded
else
{
NSNumber * numberOfRowsAffected = [NSNumber numberWithInt: dbcount(dbProc)];
bool isCountReal = dbiscount(dbProc);
NSLog(@"Command completed successfully. (%@ rows affected). (%@).",
numberOfRowsAffected,
isCountReal ? @"YES" : @"NO");
}
} // End of dbresults loop
return YES;
}
如果我通过此代码与SSMS运行查询,我会得到不同的结果:
update actor set [first_name] = 'PENELOPE' where first_name = 'PENELOPE';
SELECT * FROM actor;
update actor set [first_name] = 'NICK' where first_name = 'NICK';
SELECT * FROM actor;
SSMS:
(4 row(s) affected) (200 row(s) affected) (3 row(s) affected) (200 row(s) affected)
freetds的:
Command completed successfully. (4 rows affected). Command completed successfully. (200 results). Command completed successfully. (200 results).
查询:
SELECT * FROM actor;
update actor set [first_name] = 'PENELOPE' where first_name = 'PENELOPE';
SSMS:
(200 row(s) affected) (4 row(s) affected)
freetds的:
Command completed successfully. (200 results).
查询:
update actor set [first_name] = 'PENELOPE' where first_name = 'PENELOPE';
SELECT * FROM actor;
SSMS:
(4 row(s) affected) (200 row(s) affected)
freetds的:
Command completed successfully. (4 rows affected). Command completed successfully. (200 results).
我已通过SQL Server Profiler确认命令从SSMS和我的FreeTDS代码执行相同。
从FreeTDS代码/输出中可以看出,我永远无法获得多个受影响行数的计数。我假设我在某个地方做错了什么或者我错过了什么,但到目前为止我一直无法弄明白。我多次经历FreeTDS documentation。
有人能指出我正确的方向吗?
答案 0 :(得分:0)
认为这是FreeTDS中的问题(问题IMO,但对于其他一些问题,可能是必需的行为)。
我的解决方法是在_dbresults
方法中替换以下代码:
switch (dbproc->dbresults_state) {
case _DB_RES_INIT:
case _DB_RES_NEXT_RESULT:
dbproc->dbresults_state = _DB_RES_NEXT_RESULT;
if (done_flags & TDS_DONE_ERROR)
return FAIL;
break;
使用:
switch (dbproc->dbresults_state) {
case _DB_RES_INIT:
dbproc->dbresults_state = _DB_RES_NEXT_RESULT;
if (done_flags & TDS_DONE_ERROR)
return FAIL;
break;
case _DB_RES_NEXT_RESULT:
dbproc->dbresults_state = _DB_RES_NEXT_RESULT;
if (done_flags & TDS_DONE_ERROR)
return FAIL;
return SUCCEED;
break;
在前面的代码中,循环将继续,直到找到结果集或结果。就我而言,我希望能够匹配SSMS输出。到目前为止,在我的测试中,这似乎有效,如果我确定一切都很好,我会考虑向FreeTDS提交补丁。
我没有弄乱_DB_RES_INIT开关,因为我真的不想深入挖掘它并且这似乎不是我的问题,所以我把那个案子保留了原样。