从freetds交付多个dbcount?

时间:2015-06-11 17:25:10

标签: sql-server freetds

我有几个查询应该返回多个“受影响的行”(并且在通过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

有人能指出我正确的方向吗?

1 个答案:

答案 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开关,因为我真的不想深入挖掘它并且这似乎不是我的问题,所以我把那个案子保留了原样。