WernerK: sqlsrv_query, sqlsrv_num_rows Keine Rückgabe

Hallo,

ich versuche mich gerade mit dem PHP MSSQL Treiber und sqlsrv_query.

Die Echo Ausgabe mit numrows bringt nichts zurück, obwohl es die Tabelle mit Inhalt gibt. Ich habe auf der MS Seite gesehen, dass es für sqlsrv_query verschiedene Cursor Types gibt die man als 4. Parameter angeben kann und man auch noch einen dritten Parameter array() angeben kann / muss.

https://docs.microsoft.com/en-us/sql/connect/php/cursor-types-sqlsrv-driver

Ehrlich gesagt, verstehe ich die Parameter bzw. verschiedene Cursor nicht ganz.

Dann findet man wieder Beispiele mit DELETE und UPDATE wo es keine 3. und 4. Parameter gibt:

$stmt2 = sqlsrv_query( $conn, "delete from ScrollTest where id = 3" );  
  
//$stmt2 = sqlsrv_query( $conn, "UPDATE ScrollTest SET id = 4 WHERE id = 3" );

Was muss man bei einem INSERT machen? Braucht man hier wieder die Parameter? Vielen Dank für eine Erklärung.

Beispiel Code meines Versuches:

$sql="SELECT * FROM sysobjects WHERE name='myUsers'";
$rs = sqlsrv_query( $con, $sql);
if( $rs === false ) {
      die( print_r(sqlsrv_errors(), true));
    }
$numrows = sqlsrv_num_rows($rs);
echo "die Zeilen sind " . $numrows . "<br>";

Gruss

Werner

  1. Tach!

    Ich habe auf der MS Seite gesehen, dass es für sqlsrv_query verschiedene Cursor Types gibt die man als 4. Parameter angeben kann und man auch noch einen dritten Parameter array() angeben kann / muss.

    Erstmal nur eine generelle Antwort. Ein Cursor ist ein Zeiger. Man braucht ihn (nur) wenn man sich durch eine Datenmenge bewegt, um die aktuelle Position zu kennzeichnen. Insert/Update/Delete liefern keine Ergebnismenge, für die man einen Cursor bräuchte, um durch sie zu navigieren.

    Bisher bin ich mit Cursors (im Datenbanksinne) im Zusammenhang mit Stored Procedures in Berührung gekommen, als Äquivalent zur Fetch-Funktion, um eine Datenmenge innerhalb der Stored Procedure zu manipulieren. Vermutlich wirst du sie auch nicht brauchen, wenn es sich um handelsübliche Selects handelt. Im C#-Umfeld beim Zugreifen auf MS-SQL-Datenbanken kommt man auch ohne sie aus.

    dedlfix.

    1. Hallo dedlfix,

      hmm, ok, dann braucht man die Cursor bzw. den dritten Parameter wohl hauptsächlich bei SELECT?

      Wenn ich mir dann aber wieder das Beispiel auf der MS Seite anschaue:

      https://docs.microsoft.com/de-de/sql/connect/php/sqlsrv-fetch-array

      gibt es hier ein Select mit anschließendem fetch_arry() OHNE dritten und vierten Parameter.

      $tsql = "SELECT FirstName, LastName  
               FROM Person.Contact  
               WHERE LastName='Alan'";  
      $stmt = sqlsrv_query( $conn, $tsql);  
      if( $stmt === false)  
      {  
           echo "Error in query preparation/execution.\n";  
           die( print_r( sqlsrv_errors(), true));  
      }  
      
      /* Retrieve each row as an associative array and display the results.*/  
      while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC))  
      {  
            echo $row['LastName'].", ".$row['FirstName']."\n";  
      } 
      

      Warum benötigt man diese hier dann nicht, aber bei sqlsrv_num_rows schon?

      Gruss Werner

      1. 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.