2015-06-11 4 views
0

У меня есть несколько запросов, которые должны возвращать несколько «затронутых строк» ​​(и делать это при запуске через SQL Server Management Studio), но я не могу понять, как правильно позвонить dbcount более одного раза.Передача нескольких dbcount из freetds?

Это моя функция тестирования с помощью 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

Обнаруживает, что это проблема в 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, поскольку я действительно не хотел его копать, и это, похоже, не было моей проблемой, поэтому я оставил этот случай как есть.

Смежные вопросы