Antouly: SQL-Abfrage via ODBC

Hi,

ich versuche gerade eine SQL-Abfrage zusammenzubasteln. Die Datenbank, die ich anzusprechen versuche ist Access (kann ja auch nix dafür) und ansprechen will ich die DB mit Perl und das WIN32::ODBC Modul. Die Installation von WIN32 usw ist o.k. denn andere Abfragen klappen gut.

Nun brauche ich, um einen "rowspan"-Wert zu setzen die Anzahl der bei einer Abfrage ermittleten Datensätze und das schaut bei mir so aus:

<-- snip -->

$strAbfrage = "SELECT DISTINCT gOrt COUNT(gOrt) FROM tblGastgeber ORDER BY gOrt";

<-- snap -->

Wenn ich das ausführe, dann bekomme ich dies:

<-- snip -->

Fehler: [-3100] [1] [0] "[Microsoft][ODBC Microsoft Access 97 -Treiber] Syntaxfehler (fehlender Operator) in Abfrageausdruck 'gOrt COUNT(gOrt)'."

<-- snap -->

Wie muss der Abfragestring korrekt ausschauen und wo kommt das Resultat von Count rein?

Habt Dank im Voraus

Antouly

  1. Hi!

    $strAbfrage = "SELECT DISTINCT gOrt COUNT(gOrt) FROM tblGastgeber ORDER BY gOrt";‚

    das gOrt braucht Du nicht. es sei denn, Du schreibst
    $strAbfrage = "SELECT DISTINCT COUNT(gOrt) AS gOrt FROM tblGastgeber ORDER BY gOrt";‚

    $strAbfrage = "SELECT DISTINCT COUNT(gOrt) FROM tblGastgeber ORDER BY gOrt";
    dann steht das ergebnis im feld[0] der zeile[0] des ergebnisses.

    Gruss
    Thomas

    1. Hallo

      $strAbfrage = "SELECT DISTINCT COUNT(gOrt) FROM tblGastgeber ORDER BY gOrt";

      Wenn ich das so ausführe, dann meint er, daß die ORDER BY einen Konflikt mit DISTINCT hervorruft.

      Lasse ich dann ORDER BY auch noch weg, dann führt er die Abfrage zwar aus, aber es ist nur ein Datensatz berücksichtigt worden. Wie soll er eigentlich wissen, auf welches Feld er das DISTINCT anwenden soll, wenn ich keines angebe?

      Antouly

      1. Hi Antouly!

        Sorry, war kurz vor schluss.

        das ORDER BY kannst Du weglassen, da Du ja nicht mehrere Datensaetze zurueckgibst.

        DISTINCT oder DISTINCT ROW brauchst Du nur, wenn Du mehrere gleiche Eintraege in diesem Feld hast.

        TIP: wenn Du eh schon mit ACCESS arbeiten musst, erstell Dir die Abfrage in ACCESS und teste sie, dann brauchst Du sie nur zu kopieren.

        Gruss
        Thomas

  2. ich versuche gerade eine SQL-Abfrage zusammenzubasteln.

    Und was genau soll diese Abfrage bewirken?

    Nun brauche ich, um einen "rowspan"-Wert zu setzen
    die Anzahl der bei einer Abfrage ermittleten
    Datensätze und das schaut bei mir so aus:

    $strAbfrage = "SELECT DISTINCT gOrt COUNT(gOrt) FROM tblGastgeber ORDER BY gOrt";

    Darin sehe ich irgendwie keinen rechten Sinn.

    Du willst ein "SELECT COUNT(irgendwas)" abfragen.
    Das Ergebnis ist also *eine* Zeile (welche genau eine
    Spalte mit einer Zahl einthält).
    Wozu brauchst Du dann ein "ORDER BY", um diese 1 Zeilen
    in die richtige Reihenfolge zu bringen?

    Aber vielleicht willst Du ja die Anzahl der unterschied-
    lichen Werte in dem besagten Feld berechnen.
    Dazu könntest Du in SQL (ich nix Access, hoffentlich
    geht es auch bei Dir) Zeilen mit gleichen Werten
    zusammenfassen (GROUP BY gOrt) und dann deren Anzahl
    zählen.

    Und falls Du die Anzahl der überhaupt vorhandenen
    Zeilen berechnen willst ...
    (hust, hust, Kristallkugel etwas staubig. ;-)

    P.S.: Wenn die Anzahl Deiner Treffer nicht zu groß ist,
    dann würde ich sie komplett in einem Array ablegen,
    also erst mal puffern und den ROWSPAN daraus berechnen,
    und überhaupt kein extra-SQL-statement für die Zeilen-
    zahl, welches unnötige Last auf den DB-Server bringt.

    Und falls die Anzahl der Treffer dafür zu groß sein soll-
    te, dann wäre das von Dir daraus generierte HTML-Dokument
    wahrscheinlich ebenfalls ein ganz schöner Brummer ...

  3. Hallo auch Antouly,

    die Zeilenanzahl des Abfrageergebnisses kannst du mit der Methode RowCount() ermitteln (siehe http://www.roth.net/perl/odbc/docs/Object/#RowCount, das funktioniert jedoch nicht immer wie Dave Roth dort ausführt, also ausprobieren. Oder Du läßt eine Zählvariable mitlaufen, "solange FetchRow() Daten liefert..."(siehe I-NetLab). Ansonsten hab ich da noch einen Link zu SQL i.Allgemeinen und im Besonderen: http://www.informatik.uni-hamburg.de/Frauen/Admina/Beitraege/DB+WWW/sql-tutor/tuto_c.htm;Rolf

    1. Moin Rolf,

      das RowCount habe ich schon mal probiert, als ich das Modul von Dave Roth installiert habe. Habe ich damals schon nicht richtig hinbekommen und auch ein nochmaliger Versuch liefert immer "-1" zurück.

      Im Moment frage ich einfach zweimal ab, wobei nach der ersten eine Schleife läuft um die Anzahl festzustellen und dann hol ich mir die Daten halt nochmal.

      Kann das sein, das die Verbindung Win32::ODBC und Access sich zum einen in der Synthax und zum anderen im Leistungsumfang erheblich von vernünftigen RDBM's unterscheiden. Einige Beispiele, die ich von little-idiot oder auch aus dem ADABAS Manual probiert habe funktionieren einfach nicht so.

      Viele Grüße

      Antouly

  4. Hallo Antouly

    Mal angenommen, Du möchtest die Anzahl der unterschiedlichen Werte im Feld gOrt berechnen, dann kannst Du unter einer richtigen Datenbank (MS-SQL 7.0 *hust*, aber es sollte auch auf Oracle etc. funktionieren) folgendes SQL-Statement absetzen:

    SELECT count(*)
      FROM (SELECT DISTINCT gOrt FROM tblGastgeber As tblTemp

    Mit der MS-JetEngine (die bei Access verwendet) funktionieren jedoch geschachtelte Abfragen nicht.
    Dort müsstest Du zuerst die Abfrage 'SELECT DISTINCT gOrt FROM tblGastgeber' als z.B. 'qryTemp' erstellen und dann in der zweiten Abfrage mit 'SELECT count(*) FROM qryTemp' die Anzahl Zeilen auslesen.

    Als zweite Möglichkeit machst Du es wie von Michael beschrieben:
    Abfrage mit 'SELECT DISTINCT gOrt FROM tblGastgeber' und dann die Zeilen im zurückgelieferten Recordset zählen.
    Wie ? Das hängt von der Programmiersprache ab, in der Du arbeitest.

    Grüsse
    Tom

    1. Hallo nochmals

      SELECT count(*)
        FROM (SELECT DISTINCT gOrt FROM tblGastgeber As tblTemp

      Nun nochmal richtig:
         SELECT count(*)
         FROM (SELECT DISTINCT gOrt FROM tblGastgeber) As tblTemp

      Grüsse
      Tom

  5. Einen schönen guten Abend,

    ich bin grad nachhause gekommen und seh voll freudiger Überaschung, was sich hier bereits getan hat. Ich werd auch morgen in der Arbeit gleich alle Vorschläge durchgehen.

    Vielleicht nochmal kurz zur Situation. Die Daten liegen in einer Access-Datenbank ?! vor. Normalerweise sollte man das eine vernünftige Datenbank schmeissen, auf den Server drauf und dann könnte man das Online sauber abfragen. Nun bietet der Provider keine DB-Unterstützung an (ich habe auch keinen Einfluss auf die Auswahl des Providers) und erst Textdateien generieren und dann mit Scripten die Daten in verschiedenen Dateien zusammen zu suchen erschien mir umständlich und letztendlich wohl auch zu langsam. Also habe ich mir gedacht, ich generiere die Dateien offline und schieb sie dann auf den Server. Da sich oft was ändern kann soll dies natürlich auf Knopfdruck gehen.

    Hier geht es nun um ein Unterkunftverzeichnis und um eine Sortierung nach Ortschaften. Für diese Sortierung möchte ich ein Inhaltsverzeichnis erstellen und deshalb die Abfrage. Ich habe mal einen Entwurf im Netz stehen (allerdings manuell erstellt) und so soll das mal ausschauen, aber generiert. Im Moment wird nur eine Tabelle davon betroffen, aber es ist ja auch erst ein Inhaltsverzeichnis mit Testdaten. Für den Betrieb gibts dann noch Detailseiten und dann kommen auch mehr Tabellen ins Spiel.

    http://www.amberg-sulzbach.de/tourismus/schlafen_de/index.html

    In der Tabelle können die Namen der Ortschaften  mehrfach vorkommen (deswegen DISTINCT) und ich brauch die Ortschaften natürlich auch sortiert. Tja und die Anzahl der Treffer eben wegen der Grafik.

    Man könnte natürlich auch einfach zweimal abfragen. Beim ersten Mal die Anzahl der Treffer ermitteln (wie Rolf geschrieben hat), Inhaltsverzeichnis erstellen und dann nochmal abfragen und weiterschreiben. Ist zwar nicht sehr elegant, aber vielleicht geht das ja bei dieser Kombination (Access, Perl, Win32::ODBC) nicht anders.

    Wie auch immer, ich werde die Vorschläge morgen gleich testen.

    Bis dann

    Andy