2010-12-06 26 views
12

Ich mache dieses Projekt für die Universität, die im Grunde eine Filmdatenbank ist und für ein paar Abfragen muss ich wissen, wie viele Zeilen ausgewählt wurden. Vorerst gibt es zwei Situationen, in denen ich diese benötigen:Zählen der Anzahl der SELECTED Zeilen in Oracle mit PHP

  • Anzeige einen einziger Film Informationen. Ich möchte die Anzahl der ausgewählten Zeilen wissen, ob die Datenbank den ausgewählten Film vom Benutzer enthält. Oder gibt es dafür eine bessere Lösung?
  • Dieser ausgewählte Film hat Genres, ich muss wissen, wie viele, so dass ich eine Zeichenfolge mit den Genres durch | getrennt konstruieren kann, ohne ein Ende der Zeichenfolge hinzufügen.

Mit MySQL so einfach ist, ich Abfrage nur die Datenbank und verwenden mysql_num_rows() aber oci_num_rows() funktioniert nicht ganz das gleiche für die SELECT-Anweisung.

Die einzige Lösung, die ich mit OCI/PHP gefunden, ist dies:

if(is_numeric($mid) && $mid > 0) { 
     $stid = oci_parse($db, 
      'SELECT COUNT(*) AS NUM_ROWS 
      FROM movies 
      WHERE mid = '.$mid 
     ); 

     oci_define_by_name($stid, 'NUM_ROWS', $num_rows); 
     oci_execute($stid); 
     oci_fetch($stid); 

     if($num_rows > 0) { 
      $stid = oci_parse($db, 
       'SELECT title, year, synopsis, poster_url 
       FROM movies 
       WHERE mid = '.$mid 
      ); 

      oci_execute($stid); 

      $info = oci_fetch_assoc($stid); 

      $stid = oci_parse($db, 
       'SELECT COUNT(*) AS NUM_ROWS 
       FROM genres g, movies_genres mg 
       WHERE mg.mid = '.$mid.' AND g.gid = mg.gid' 
      ); 

      oci_define_by_name($stid, 'NUM_ROWS', $num_rows); 
      oci_execute($stid); 
      oci_fetch($stid); 

      $stid = oci_parse($db, 
       'SELECT g.name AS genre 
       FROM genres g, movies_genres mg 
       WHERE mg.mid = '.$mid.' AND g.gid = mg.gid'); 

      oci_execute($stid); 

      $genres_list = null; 

      while($row = oci_fetch_assoc($stid)) { 
       $genres_list .= $row['GENRE']; 

       if($num_rows > 1) { 
        $genres_list .= ' | '; 
        $num_rows--; 
       } 
      } 

      $Template->assignReferences(array(
       'Index:LinkURI' => $link_uri, 
       'Movie:Title'  => $info['TITLE'], 
       'Movie:Year'  => $info['YEAR'], 
       'Movie:GenresList' => $genres_list, 
       'Movie:Synopsis' => $info['SYNOPSIS'], 
       'Movie:PosterURL' => $info['POSTER_URL'] // FIX: Handle empty poster link 
      )); 

      $Template->renderTemplate('movieinfo'); 
     } else { 
      // TODO: How to handle this error? 
     } 
    } else { 
     // TODO: How to handle this error? 
    } 

Aber ich mag es nicht. Ich muss immer 2 Abfragen machen, um die Zeilen zu zählen, und dann die tatsächlichen Daten auswählen, und es gibt zu viele Codezeilen, nur um die Zeilen zu zählen.

Dieser Code zeigt es nicht (habe es noch nicht getan, weil ich nach einer besseren Lösung suche), aber ich muss auch das gleiche für die Filmregisseure machen.

Gibt es bessere und einfacher Lösung, um dies zu erreichen, oder das ist der einzige Weg?

Ich könnte Trennzeichen in der Fetch-Schleife hinzufügen, bis es beendet und dann PHP-Funktionen verwenden, um das letzte Trennzeichen aus der Zeichenfolge zu trimmen, aber für dieses Projekt bin ich gezwungen, SEQUENZEN, ANSICHTEN, FUNKTIONEN, VERFAHREN und TRIGGER zu verwenden. Kann ich Ihnen helfen, mein Problem zu lösen?

Ich weiß, was SEQUENZEN sind, ich benutze sie bereits, aber ich sehe nicht, wie sie helfen können.

Für VIEWS, würden sie wahrscheinlich nicht den Code so viel vereinfachen (es ist im Grunde eine gespeicherte Abfrage richtig?). Für FUNKTIONEN, VERFAHREN und TRIGGERS, soweit ich sie verstehe, kann ich nicht sehen, wie sie auch helfen können.

Lösungen?

+0

+1 für die Kennzeichnung als Hausaufgabe – Knubo

+0

Ist Ihr DB-Schema festgelegt oder sollten Sie es erstellen? – Knubo

+0

Wie ist oci_num_rows anders? – Breezer

Antwort

5

Warum zählt die anfängliche Zählung überhaupt? Gib einfach deine Auswahl für den Filmtitel aus. Wenn es nicht gefunden wird, machen Sie Ihre Fehlerverarbeitung. Wenn ja, mach weiter! Wenn Sie wirklich die Zählung benötigen, verwenden Sie ein analytisches die Zählung zu Ihrer Anfrage hinzuzufügen:

'SELECT title, year, synopsis, poster_url 
     , COUNT(*) OVER (PARTITION BY mid) mcount 
    FROM movies 
    WHERE mid = '.$mid 

Das gleiche gilt für Ihre Genreauswahl- geht.

EDIT:

Oracle-Dokumentation auf Analytic Functions link. Ich habe festgestellt, dass Analytik aus den Oracle-Dokumenten heraus schwer zu bekommen ist. Analytic functions by Example by Shouvik Basu bietet einige einfache Anleitungen, wie man sie benutzt und hat mir ziemlich geholfen.

+0

Ich wusste nicht, dass Sie das tun könnten, ich dachte, das Ergebnis von 'oci_fetch_assoc()' (oder ähnliche Funktionen) würde immer etwas Wahres zurückgeben, aber ich erkannte gerade, dass sie falsch zurückgeben, wenn nichts ausgewählt wurde, danke. Wie für die Zählung, nur getestet, und es scheint gut zu funktionieren, aber ich verstehe es nicht, wo kann ich mehr darüber lesen? (Ich kann nie richtiges Handbuch für Oracle SQL-Anweisungen finden). –

+1

Bearbeitete meine Antwort, um einige Links für Analysen zur Verfügung zu stellen. – DCookie

1

können Sie die ocirowcount es einfach verwenden, wie mysql_num_rows verhalten sollte, wenn eine ausgewählte

+0

Wie sicher ist das? Ich meine, das PHP-Handbuch besagt, dass ocirowcount ein Alias ​​für oci_num_rows ist, sich aber anders verhält. Wie stehen die Chancen, dass dieses Verhalten in Zukunft "behoben" wird? –

+1

sollten Sie DCookies verwenden, beantworten Sie es ist besser – Breezer

+0

Dieser Alias ​​wurde veraltet, verwenden Sie stattdessen oci_num_rows() –

2

machen können Sie versuchen, diese

$conn = oci_pconnect('user', 'password', 'connectionstring'); 
$resource = oci_parse($conn, $sql); 
oci_execute($resource, OCI_DEFAULT); 

$results=array(); 
$numrows = oci_fetch_all($resource, $results, null, null, OCI_FETCHSTATEMENT_BY_ROW); 

Prost

0

oci_num_rows() Wollen Sie die gesamte Zeile geben zählen, wenn ausgeführt nach oci_fetch_array()

Verwandte Themen