Multi: Liste mit reservierten Wörtern

Mahlzeit,
gibt es eine Liste von Schlüsselwörtern (z.B. LIKE, REGEX usw.) für Mysql, MSSql, Oracle und PostgrSQL?

Ich brauch nur eine Liste, ich will nicht die ganzen Dokus nach jeder einzelnen Funktion durchforsten. Hab zumindest in der Doku zu MySQL nix gefunden.

Ich brauch diese Liste zur Auswertung in einer Klasse, die Querys automatisch zusammenbaut und über bestimmte Teile ein mysql_real_escape_string (aktuell ist die Klasse nur für Mysql, wird aber später auf andere Systeme erweitert) gejagt.

thx4hlp

  1. Hallo,

    gibt es eine Liste von Schlüsselwörtern (z.B. LIKE, REGEX usw.) für Mysql, MSSql, Oracle und PostgrSQL?

    ja, es gibt solche Listen. Sie sind nicht besonders schwierig zu finden :-)

    Ich brauch nur eine Liste, ich will nicht die ganzen Dokus nach jeder einzelnen Funktion durchforsten. Hab zumindest in der Doku zu MySQL nix gefunden.

    nein? Kapitel Language Structure, Abschnitt Reserved Words

    Ich brauch diese Liste zur Auswertung in einer Klasse, die Querys automatisch zusammenbaut und über bestimmte Teile ein mysql_real_escape_string (aktuell ist die Klasse nur für Mysql, wird aber später auf andere Systeme erweitert) gejagt.

    das ist falsch. Reservierte Wörter sind in Zeichenketten überhaupt kein Problem. Sie sind dann ein Problem, wenn sie als Identifier für Spalten, Tabellen oder ähnliches verwendet werden. Die Behandlung ist selbstverständlich eine andere als die für Zeichenketten.

    MySQL verwendet dafür standardmäßig Backticks, z.B. LIKE kann aber auch in den Modus ANSI-Quotes gebracht werden: dann sind's doppelte Anführungszeichen, d.h. "LIKE".

    T-SQL (z.B. MS-SQL) packt solche Namen in eckige Klammern [LIKE], kann aber auch in den Modus ANSI-Quotes gebracht werden: dann sind's doppelte Anführungszeichen, d.h. "LIKE".

    DB2 verwendet soweit ich mich erinnere standardmäßig ANSI-Quotes, d.h. "LIKE".
    Wenn PostgreSQL Quotes verwendet, werden Namen case-sensitive, ohne Quotes sind sie's nicht ...

    Deswegen: die beste Strategie ist: immer quoten, so wie es phpMyAdmin macht, so wie es das SQL-Management-Studio von Microsoft macht.

    Oracle überlasse ich anderen ;-)

    Freundliche Grüße

    Vinzenz

    1. ja, es gibt solche Listen. Sie sind nicht besonders schwierig zu finden :-)

      Tja, vermutlich hatte ich nicht die richtigen Suchbegriffe oder war einfach blind ;)

      nein? Kapitel Language Structure, Abschnitt Reserved Words

      Danke, aber ich habs vorher echt nicht gefunden. Vielleicht werd ich langsam alt ...

      das ist falsch. Reservierte Wörter sind in Zeichenketten überhaupt kein Problem. Sie sind dann ein Problem, wenn sie als Identifier für Spalten, Tabellen oder ähnliches verwendet werden. Die Behandlung ist selbstverständlich eine andere als die für Zeichenketten.

      Probleme macht das aber, wenn aus einem String LIKE "%test%"  nach dem Quten ein LIKE "%test%" wird und dadurch die Abfrage fehlschlägt bzw. nen Fehler wirft.

      MySQL verwendet dafür standardmäßig Backticks, z.B. LIKE kann aber auch in den Modus ANSI-Quotes gebracht werden: dann sind's doppelte Anführungszeichen, d.h. "LIKE".

      Darum gehts. Wenn ich ein WHERE-Statement zusammenbaue, soll z.B. LIKE nicht gequotet werden, deshalb brauch ich die Liste um zu wissen, was nicht gequotet werden soll.

      T-SQL (z.B. MS-SQL) packt solche Namen in eckige Klammern [LIKE], kann aber auch in den Modus ANSI-Quotes gebracht werden: dann sind's doppelte Anführungszeichen, d.h. "LIKE".

      DB2 verwendet soweit ich mich erinnere standardmäßig ANSI-Quotes, d.h. "LIKE".
      Wenn PostgreSQL Quotes verwendet, werden Namen case-sensitive, ohne Quotes sind sie's nicht ...

      Das schau ich mir an, danke für die Links.

      Deswegen: die beste Strategie ist: immer quoten, so wie es phpMyAdmin macht, so wie es das SQL-Management-Studio von Microsoft macht.

      Ja, wenn es nötig ist, soll das passieren. Wenn die Schlüsselwörter aber dahingehören, solls eben nicht gequotet werden

      Oracle überlasse ich anderen ;-)

      Da das aktuell nicht eilt, kein Problem ;)

      Danke :)

      1. Hallo,

        Darum gehts. Wenn ich ein WHERE-Statement zusammenbaue, soll z.B. LIKE nicht gequotet werden, deshalb brauch ich die Liste um zu wissen, was nicht gequotet werden soll.

        die Listen der Schlüsselwörter und der reservierten Wörter sind nicht identisch, das siehst Du sehr schön an der PostgreSQL-Seite ...

        Freundliche Grüße

        Vinzenz

        1. die Listen der Schlüsselwörter und der reservierten Wörter sind nicht identisch, das siehst Du sehr schön an der PostgreSQL-Seite ...

          Davon geht ich aus. Deshalb schreib ich für jedes System eine eigene Klasse die per Konfiguration ausgewählt wird.

      2. Tach!

        Wenn ich ein WHERE-Statement zusammenbaue, soll z.B. LIKE nicht gequotet werden, deshalb brauch ich die Liste um zu wissen, was nicht gequotet werden soll.

        Hast du schon darüber nachgedacht, Prepared Statements zu verwenden? Wie sollen denn deine Statements zusammengebaut werden? Wo kommen die einzelnen Teile der Query her?

        dedlfix.

        1. Hast du schon darüber nachgedacht, Prepared Statements zu verwenden?

          Ist auch möglich, ebenso wie Raw-Querys.

          Wie sollen denn deine Statements zusammengebaut werden? Wo kommen die einzelnen Teile der Query her?

          Ich rufe zum Schreiben, Ändern, Löschen entsprechende Methoden auf.

          [code  lang=php]
          $db->read_array($Tabelle, $Spalten, $Where, $Order, $Limit, $Key);
          [/code]

          Dabei sind die Parameter teilweise optional. $Key wird, wenn angegeben der Schlüssel im zurückgegebenen Array, wird $Key nicht angegeben, bleiben die nurmerischen Indizes aus Mysql erhalten.

          Und da z.B. $Where ein NOT NULL, LIKE oder sonstige Schlüsselwörter  enthalten kann, muss ich das erkennen, bevor ich $Where durch mysql_real_escape_string schiebe.

          Ob das performant genug ist, muss ich erst noch probieren, aber das System an sich funktioniert gut. Der Vorteil, man muss nicht Querys für jede Datenbank erzeugen sondern das übernimmt die Methode für den Programmierer. Das Ganze ist Teil einer API für mein Framework/CMS

          1. Tach!

            Und da z.B. $Where ein NOT NULL, LIKE oder sonstige Schlüsselwörter  enthalten kann, muss ich das erkennen, bevor ich $Where durch mysql_real_escape_string schiebe.

            Ich würde zwei Wege vorsehen. Der erste und einfache und vermutlich am häufigsten benötigte, wäre ein Array zu übergeben, das Schlüssel-Wert-Paare enthält und damit "WHERE schlüssel='wert' AND so weiter" produziert. Schlüssel und Wert jeweils passend maskiert.

            Für die zweite Variante würde ich die Übergabe eines Strings vorsehen, der eine fertig formulierte WHERE-Klausel entgegennimmt. Damit ist der Programmierer flexibel. Da er vermutlich auch an anderen Stellen noch genügend Kontextwechsel beachten muss, würde ich ihm hier an dieser Stelle die Arbeit auch nicht abnehmen wollen, zumal du in deinem Code nur die gegebene Syntax und nicht die Intention dahinter analysieren kannst. Ich würde dabei lediglich Platzhalter in zwei Versionen (Indentifier, Values) vorsehen, für die eine Ersetzung mit gegebenen Parametern erfolgt.

            dedlfix.

          2. Hello,

            Dabei sind die Parameter teilweise optional. $Key wird, wenn angegeben der Schlüssel im zurückgegebenen Array, wird $Key nicht angegeben, bleiben die nurmerischen Indizes aus Mysql erhalten.

            Und da z.B. $Where ein NOT NULL, LIKE oder sonstige Schlüsselwörter  enthalten kann, muss ich das erkennen, bevor ich $Where durch mysql_real_escape_string schiebe.

            Du musst außerdem erkennen, ob in der API eine Typisierung und Kontrolle z.B. auf numerische Werte, logische Werte usw. durchgeführt werden muss und/oder eine Quotierung für Strings stattfinden muss oder für logische oder numerische Rechenwerte nicht darf.

            Das Ganze wird daher doch etwas komplexer, als Du denkst.

            Es ist jetzt aber wichtig zu entscheiden, in welcher Schicht welche Aufgabe zu erfüllen ist.

            HTML
            API
              Benutzerrechte, horizontal (*)
            DBAL
              DBMS-STATEMENT-ÜBERSETZER
                Benuterrechte, vertikal (*)
              DBMS-Zugriffsmethoden (Direkte Statements, Stored Procedures, Benutzerdefinierte Funktionen)
            DATENBANK

            Und für die Erzeugung des HTML-Formulars das Ganze auch rückwärts.

            (*) Wo nun genau die Benutzerrechte zu prüfen sind und dann Einfluss auf die weiteren Verfahren haben, darüber lässt sich trefflich streiten.

            Liebe Grüße aus dem schönen Oberharz

            Tom vom Berg

            --
             ☻_
            /▌
            / \ Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
          3. Moin!

            Ich rufe zum Schreiben, Ändern, Löschen entsprechende Methoden auf.

            [code  lang=php]
            $db->read_array($Tabelle, $Spalten, $Where, $Order, $Limit, $Key);
            [/code]

            Dabei sind die Parameter teilweise optional. $Key wird, wenn angegeben der Schlüssel im zurückgegebenen Array, wird $Key nicht angegeben, bleiben die nurmerischen Indizes aus Mysql erhalten.

            Und da z.B. $Where ein NOT NULL, LIKE oder sonstige Schlüsselwörter  enthalten kann, muss ich das erkennen, bevor ich $Where durch mysql_real_escape_string schiebe.

            Du kannst einem String nicht ohne weiteres ansehen, wie er gemeint ist. Dein System wird scheitern, weil du effektiv einen kompletten SQL-Query-Parser bauen müsstest, um dann zu analysieren, an welcher Stelle die Fails durch fehlendes Escaping drinstecken. Sowas geht nicht, denn wenn es ginge, wäre das schon dort eingebaut, wo jetzt bereits funktionierende Query-Parser eingebaut sind: In der Datenbank!

            Nur mal als Beispiel: $where = "LIKE = 'NOT'"; Das ist jetzt korrekt escaped, es muss also nichts mehr getan werden. Was würde dein System draus machen?

            Du brauchst keinen String, sondern Objekte, die du als Where-Bedingung zusammensetzen kannst, und die auf Anforderung zu einem korrekt escapeten String werden. Dein Parameter $where darf nur so ein Objekt akzeptieren.

            An dieser Stelle könntest du allerdings auch gleich abbrechen und stattdessen einen ORM-Layer wie Doctrine benutzen. Dort sind alle Sicherheitsprobleme mit Escaping schon erkannt und mutmaßlich ausreichend behandelt, und du musst dich auch nicht um unterschiedliche Datenbanken kümmern - das erledigt bereits die Entwicklercommunity.

            Ob das performant genug ist, muss ich erst noch probieren, aber das System an sich funktioniert gut. Der Vorteil, man muss nicht Querys für jede Datenbank erzeugen sondern das übernimmt die Methode für den Programmierer. Das Ganze ist Teil einer API für mein Framework/CMS

            Jeder Programmierer sollte einmal im Leben ein Framework versuchen zu schreiben. Und es dann wegwerfen, und stattdessen eines der existierenden großen Alternativen nehmen. Andernfalls erzeugt man sich viele schöne zukünftige Probleme.

            - Sven Rautenberg

            1. An dieser Stelle könntest du allerdings auch gleich abbrechen und stattdessen einen ORM-Layer wie Doctrine benutzen. Dort sind alle Sicherheitsprobleme mit Escaping schon erkannt und mutmaßlich ausreichend behandelt, und du musst dich auch nicht um unterschiedliche Datenbanken kümmern - das erledigt bereits die Entwicklercommunity.

              Das schau ich mir mal an. Danke für den Hinweis

              Jeder Programmierer sollte einmal im Leben ein Framework versuchen zu schreiben. Und es dann wegwerfen, und stattdessen eines der existierenden großen Alternativen nehmen. Andernfalls erzeugt man sich viele schöne zukünftige Probleme.

              Ich gehe davon aus, das würden mir meine Kunden übel nehmen. Aktuell gibt es ca. 300 Installationen von meinem System, von denen ich weiss (Das Framework selbst ist Opensource und kostenlos) und es werden dieses Jahr noch wesentlich mehr werden, da ich eine Sonderlösung für Webradios anbieten werde, die Features enthält, die es so noch nicht gibt. Und da ich, aufgrund dieses Frameworks, kostenpflichtige Speziallösungen anbiete (das verbreiteste ist mein Modul für Immobilienmakler), macht es absolut keinen Sinn, dass ich alles in einem anderen Framework neu programmiere.

              Ich halte deine pauschale Aussage für schlichtweg falsch und im Bereich der Softwarevielfalt für Kontraproduktiv.