Я использую следующий код PHP для взаимодействия с базой данных MS Access.
$odbc_con = new COM("ADODB.Connection");
$constr = "DRIVER = {Microsoft Access Driver (*.mdb)}; DBQ = " . $db_path . ";";
$odbc_con -> open($constr);
$rs_select = $odbc_con -> execute ("SELECT * FROM Main");
Использование ($rs_select -> RecordCount) дает -1, хотя запрос возвращает ненулевые записи.
а) В чем может быть причина? б) Есть ли выход?
Я также пробовал использовать count($rs_select -> GetRows()). Это удовлетворяет потребность, но выглядит неэффективным, поскольку сначала необходимо скопировать все записи в массив.






У Access нет собственного оператора COUNT? например:
$rs_select = $odbc_con -> execute ("SELECT COUNT(*) FROM Main");
Это нежелательно, так как это приведет к нескольким SQL-запросам - один для подсчета, а другой для получения записей. Цель состоит в том, чтобы получить набор записей и проверить его количество записей, чтобы подтвердить его.
Единственные другие варианты, которые я вижу (которые у вас уже есть), включают ненужную отправку большого количества данных для их подсчета. Намного более разумным кажется запуск дополнительного небольшого запроса.
Возможно, ODBC еще не знает количество записей. В этом случае можно перейти к последней записи, и только тогда количество записей будет отражать истинное количество записей. Это, вероятно, также будет не очень эффективным, поскольку загрузит все записи из запроса.
Как сказал Оли, использование SELECT COUNT(*) даст вам результат. Я думаю, что использование двух запросов все равно будет более эффективным, чем использование моего первого метода.
По сути, Access не будет показывать вам весь набор записей до тех пор, пока это не понадобится (в любом случае, это быстрее для большей части пользовательского опыта) - особенно с большими наборами записей.
Чтобы получить точный подсчет, вы должны пройти весь набор записей. В VBA я обычно делаю это с помощью дуэта foo.MoveLast и foo.MoveFirst - я не знаю, каковы эквиваленты php. Это дорого, но, поскольку похоже, что вы все равно собираетесь обрабатывать весь набор записей, я думаю, что это нормально.
(примечание стороны, этот же обход также необходим, если вы манипулируете закладками в VBA, поскольку вы можете получить некоторые дикие результаты, если клонируете набор записей и не проходите его, прежде чем скопировать закладку обратно в набор записей формы)
На самом деле это зависит от интерфейса данных, который вы используете. Наборы записей DAO возвращают количество записей, равное 1 или более, если записи возвращаются, и 0, если не возвращаются никакие, но нельзя доверять точному количеству записей до тех пор, пока вы не введете команду .MoveLast. ADO и ODBC разные.
ADODB имеет свои собственные правила для того, какое количество записей возвращается в зависимости от типа набора записей, который вы определили. Видеть:
В приведенном выше примере объект PHP COM () используется для создания ADODB, COM-интерфейса для общего доступа к базе данных. Согласно Документация PHP, созданная ссылка на объект перегружена, поэтому вы можете просто использовать те же свойства / методы, что и собственный объект ADODB. Это означает, что вам нужно использовать методы ADODB, чтобы установить тип набора записей, который даст точное количество записей (если оно вам необходимо). Альтернативой, как упоминали другие, является использование второго запроса для получения COUNT () записей, возвращаемых оператором SELECT. Это проще, но может быть неуместным в конкретной среде.
Я не гуру ADO, поэтому не могу предоставить вам точные команды для установки типа набора записей, но из статей, процитированных выше, ясно, что вам нужен статический курсор или курсор с набором клавиш. Мне кажется, что правильный метод установки CursorType - использовать параметр в команде, которая открывает набор записей. Эта статья W3C Schools о свойстве CursorType дает соответствующие аргументы для этой команды.
Надеюсь, эта информация поможет оригинальному плакату так или иначе выполнить свою задачу.
Если вы используете тип соединения с динамическим курсором, он действительно может измениться. Кто-то может удалить запись из этой базы данных, пока вы просматриваете страницы записей. Чтобы избежать этого, используйте статический вид курсора моментального снимка. У меня есть эта закладка, которая хорошо это объяснит. Это всегда меня привлекало, и закладка всегда напоминала мне, почему.
http://support.microsoft.com/kb/194973
... но Jet не поддерживает динамические курсоры! Когда запрашивается динамический курсор, вы получаете курсор с набором ключей, но его значение перекрывается как «Я использую динамический SQL» (в отличие от подготовленного оператора или сохраненной процедуры), и механизм оптимизируется соответствующим образом, т.е. запрос динамического курсора является хорошая вещь.
MS Access здесь не задействован, только ядро базы данных Jet.