Tach!
Warum benötigt man diese [Cursors] hier dann nicht, aber bei sqlsrv_num_rows schon?
Die num_rows-Funktionen können nur dann ein verwertbares Ergebnis liefern, wenn sie in der Lage sind, alle Datensätze der Ergebnismenge zu zählen. Sie werden beim Client ausgeführt und nicht im DBMS. Um lediglich die Nummer zu bekommen ist SELECT COUNT() …
die bessere Wahl, weil dabei nur ein Ergebniswert entsteht und nicht die ganze Menge lediglich zum Zwecke des Zählens übertragen werden muss.
Die MySQL-Client-API beispielsweise holt bei einer Query die gesamte Ergebnismenge im Hintergrund ab und legt sie in einen Zwischenspeicher. Nur so kann sie die Ergebnismenge mit mysqli_num_rows() durchzählen. Notwendig ist dazu aber, dass man nicht die Query nicht unbuffered ausführt (Standard: buffered).
Bei MS-SQL bestimmt der Cursor ein vergleichbares Verhalten.
SQLSRV_CURSOR_STATIC - Lets you access rows in any order …
SQLSRV_CURSOR_KEYSET - Lets you access rows in any order. …
im Gegensatz zu
SQLSRV_CURSOR_FORWARD - Lets you move one row at a time …
Beim Forward-Cursor hat man also immer nur einen Datensatz am Wickel und kennt die Größe der Restmenge nicht. Um "in any order" zugreifen zu können, besonders mit First, Last, Absolute und Relative, braucht man die Kenntnis von den Grenzen der Menge.
Warum es aber bei SQLSRV_CURSOR_CLIENT_BUFFERED nicht gehen soll, entzieht sich meiner Kenntnis. Vielleicht ein Dokumentationsfehler. Aber auch SQLSRV_CURSOR_DYNAMIC hat "access rows in any order", aber da soll sqlsrv_num_rows nicht wollen laut Doku.
dedlfix.