23 декабря 2007

ADO::Recordset::Seek()

Изменить (или удалить) несколько записей в ADO::Recordset, источником которого служит база данных Microsoft Jet, можно довольно понятным подходом:
1. открывается нужная таблица в виде ADO::Recordset (с CursorLocation = adUseServer)
2. задается индекс, по которому будут отыскиваться записи
3. вызывается Seek() для быстрого переходу по ключу индекса
4. выполняется Update() (или Delete())
повторить п.п.3-4 нужное количество раз
5. закрыть открытый ADO::Recordset

Самое удивительное, что когда источник - MS SQL Server, такой подход не прокатит. Дело в том, что его провайдер SQL сервера не поддерживает метод Seek(). В инете миллион вопросов почему "оно" не работает. Ответ печальный: by design.

Я было заменил Seek() на Find() и расслабился. Понятное дело, ненадолго. На реальных данных все это жутко затормозило и понятное дело почему. Когда в таблице миллион записей, ждать Find() приходится очень долго - тупой перебор записей оказывается штукой довольно тормознутой.

Но ведь индекс-то есть, и нужно использовать его. И раз Seek() не работает, выход один - открывать на каждую запись свой рекордсет вида "Select * From [Table] Where [KeyField]=KeyValue". Не забываем Recordset->CursorLocation = adUseServer.