t.sebesta: doppeltes %-Zeichen?

Folgendes Problem:
Wert in der Datenbank: "Film und Utopie"

Suche per LIKE '%Wert%'
ergibt bei Großschreibung "Film und Utopie" einen Treffer, bei Kleinschreibung "film und utopie" keinen Treffer, wobei es nur auf den ersten Buchstaben ankommt. Ob "Utopie" groß oder klein geschrieben wird ist egal - ändert nichts am Verhalten.

Suche ich mit LIKE '%%Wert%%' wird in allen Fällen ein Treffer ausgegeben.

Ich verstehe nur nicht warum? Sollte nicht auch die erste Variante jedenfalls Treffer ausgeben?

Gruß
Thomas

  1. Hi!

    Wert in der Datenbank: "Film und Utopie"
    Suche per LIKE '%Wert%'
    ergibt bei Großschreibung "Film und Utopie" einen Treffer, bei Kleinschreibung "film und utopie" keinen Treffer,

    Das dürfte bei dem 'Wert' überhaupt keinen Treffer ergeben. Bitte nachvollziehbare Beispiel angeben und nicht irgendwas.

    wobei es nur auf den ersten Buchstaben ankommt. Ob "Utopie" groß oder klein geschrieben wird ist egal - ändert nichts am Verhalten.

    Groß- und Kleinschreibung wird anhand der Kollation des Feldes berücksichtigt oder nicht.

    Suche ich mit LIKE '%%Wert%%' wird in allen Fällen ein Treffer ausgegeben.
    Ich verstehe nur nicht warum? Sollte nicht auch die erste Variante jedenfalls Treffer ausgeben?

    Ich auch nicht, weil der 'Wert' kein nachvollziehbares Besipiel ergibt.

    Lo!

    1. Wert in der Datenbank: "Film und Utopie"
      Suche per LIKE '%Wert%'
      ergibt bei Großschreibung "Film und Utopie" einen Treffer, bei Kleinschreibung "film und utopie" keinen Treffer,

      Das dürfte bei dem 'Wert' überhaupt keinen Treffer ergeben. Bitte nachvollziehbare Beispiel angeben und nicht irgendwas.

      Hat er doch. Einmal ist der 'Wert' 'Film und Utopie' beim anderen Mal 'film und utopie'. Was willst Du da noch genauer wissen?

      1. Hi!

        Wert in der Datenbank: "Film und Utopie"
        Suche per LIKE '%Wert%'
        ergibt bei Großschreibung "Film und Utopie" einen Treffer, bei Kleinschreibung "film und utopie" keinen Treffer,
        Das dürfte bei dem 'Wert' überhaupt keinen Treffer ergeben. Bitte nachvollziehbare Beispiel angeben und nicht irgendwas.
        Hat er doch. Einmal ist der 'Wert' 'Film und Utopie' beim anderen Mal 'film und utopie'. Was willst Du da noch genauer wissen?

        Nun,

        SELECT 'Film und Utopie' LIKE '%Wert%', 'film und utopie' LIKE '%Wert%', 'Film und Utopie' LIKE '%%Wert%%', 'film und utopie' LIKE '%%Wert%%'

        liefert bei mir 4 × 0, trifft also in keinem Fall zu. Laut seiner Aussage ergibt es aber bei ihm irgendwelche Treffer. Also wird er mit irgendwas anderem als '%Wert%' vergleichen wollen. Da ich nicht weiß, was er da konkret nimmt, ist es für mich nicht nachvollziehbar.

        Lo!

        1. Hm.

          Vielelicht haben GRandmasterA und ich ja hellseherische Faehigkeiten entwickelt. Aber

          SELECT 'Film und Utopie' LIKE '%Wert%', 'film und utopie' LIKE '%Wert%', 'Film und Utopie' LIKE '%%Wert%%', 'film und utopie' LIKE '%%Wert%%'

          hat er wohl auch nicht. Vielmehr duerfte das ungefaehr so aussehen:

          SELECT * FROM Filmdatenbank WHERE Titel LIKE '%Film und Utopie%' - liefert Daten
          SELECT * FROM Filmdatenbank WHERE Titel LIKE '%Film und utopie%' - liefert Daten
          SELECT * FROM Filmdatenbank WHERE Titel LIKE '%film und utopie%' - liefert nix
          SELECT * FROM Filmdatenbank WHERE Titel LIKE '%%film und utopie%%' - liefert Daten

          Finde ich nachvollziehbar erlaeutert.

          --
          Vergesst Chuck Norris.
          Sponge Bob kann unter Wasser grillen!
          1. Om nah hoo pez nyeetz, Steel!

            SELECT * FROM Filmdatenbank WHERE Titel LIKE '%Film und Utopie%' - liefert Daten SELECT * FROM Filmdatenbank WHERE Titel LIKE '%Film und utopie%' - liefert Daten SELECT * FROM Filmdatenbank WHERE Titel LIKE '%film und utopie%' - liefert nix SELECT * FROM Filmdatenbank WHERE Titel LIKE '%%film und utopie%%' - liefert Daten

            Finde ich nachvollziehbar erlaeutert.

            Ich denke auch, dass das so gemeint ist und dass dies auch so dem OP entnehmbar ist:

            Wert in der Datenbank: "Film und Utopie"

            Suche per LIKE '%Wert%'

            Matthias

            --
            1/z ist kein Blatt Papier. http://www.billiger-im-urlaub.de/kreis_sw.gif
            1. Hoi!

              Ich denke auch, dass das so gemeint ist und dass dies auch so dem OP entnehmbar ist:

              Auch die neue HD Glaskugel ausm Media Markt gekauft? ;)

              --
              Vergesst Chuck Norris.
              Sponge Bob kann unter Wasser grillen!
              1. Auch die neue HD Glaskugel ausm Media Markt gekauft? ;)

                Braucht man nicht. Logisches Mitdenken reicht...
                Man kann sich natürlich auch dumm stellen, wenn man das Ausgangsposting nicht verstehen WILL. Ansonsten ist es eigentlich gut genug beschrieben.

                1. Auch die neue HD Glaskugel ausm Media Markt gekauft? ;)

                  Braucht man nicht. Logisches Mitdenken reicht...
                  Man kann sich natürlich auch dumm stellen, wenn man das Ausgangsposting nicht verstehen WILL. Ansonsten ist es eigentlich gut genug beschrieben.

                  Hm. Heisst das jetzt, man kann lernen das auch ohne Glaskugel zu koennen oder sogar, dass Media Markt mir ueberteuerten Mist angedreht hat? o.O

                  ;)

                  --
                  Vergesst Chuck Norris.
                  Sponge Bob kann unter Wasser grillen!
                2. Hi!

                  Man kann sich natürlich auch dumm stellen, wenn man das Ausgangsposting nicht verstehen WILL. Ansonsten ist es eigentlich gut genug beschrieben.

                  Gut, ihr habt ja einige Interpretationsmöglichkeiten geliefert. Das Problem ist nur, dass bisher mit keiner die Problembeschreibung nachvollziehbar ist. Alle Interpretationen liefern ein Ergebnis, das ich erwarte. Der OP erzählt jedoch von einem anderen.

                  Lo!

                  1. Gut, ihr habt ja einige Interpretationsmöglichkeiten geliefert. Das Problem ist nur, dass bisher mit keiner die Problembeschreibung nachvollziehbar ist. Alle Interpretationen liefern ein Ergebnis, das ich erwarte. Der OP erzählt jedoch von einem anderen.

                    Der OP spricht von diesem hier: (aus meinem ersten Posting)

                    SELECT * FROM Filmdatenbank WHERE Titel LIKE '%film und utopie%' - liefert nix

                    Wenn der Titel was mit 'Film und Utopie' ist sollte das greifen, was z.B. '%Film und utopie%' ( und eben auch '%%film und utopie%%') scheinbar tut.

                    Kann mir nur vorstellen, dass der OP da ein paar Copy&Paste oder Tippfehler hatte.

                    --
                    Vergesst Chuck Norris.
                    Sponge Bob kann unter Wasser grillen!
                    1. Erstens: MySQL ist richtig
                      Zweitens: die Abfrage endet mit "WHERE {Book}.Title LIKE '%%$value%%'"

                      Was mit komisch vorkommt ist, dass das Abfrageverhalten abhängig ist von einem doppelten %-Zeichen. Das habe ich nirgends dokumentiert gefunden.

                      Setze ich den Suchwert zwischen einfache %-Zeichen, so ist das Abfrageverhalten wie beschreiben. Wird der Anfang des Suchstring klein geschrieben wird nichts gefunden, wird er Groß geschrieben, so wird der Feldinhalt gefunden.

                      Setze ich den Suchwert zwischen doppelte %-Zeichen, so funktioniert die Abfrage wie gewünscht. Egal wie ich den Suchstring schreibe, es wird immer der Datensatz gefunden.

                      Wo finde ich die Angabe zur Collation? Ich glaube was mit utf8?

                      1. Hi!

                        Erstens: MySQL ist richtig
                        Zweitens: die Abfrage endet mit "WHERE {Book}.Title LIKE '%%$value%%'"

                        Das ist nicht das Statement sondern irgendwelcher Code, der ein Statement zusammenbaut.

                        Was mit komisch vorkommt ist, dass das Abfrageverhalten abhängig ist von einem doppelten %-Zeichen. Das habe ich nirgends dokumentiert gefunden.

                        Wenn dieser dein Code das %% zu einem % interpretiert, wie es beispielsweise PHPs sprintf() macht, dann ...

                        Mach mal lieber eine Kontrollausgabe des fertigen Statements.

                        Setze ich den Suchwert zwischen einfache %-Zeichen, so ist das Abfrageverhalten wie beschreiben. Wird der Anfang des Suchstring klein geschrieben wird nichts gefunden, wird er Groß geschrieben, so wird der Feldinhalt gefunden.

                        Groß-Kleinschribung ist von der Kollation des Feldes abhängig, wobei hier üblicherweise nur bin(ary) oder nicht (=*_ci) in Frage kommt.

                        Wo finde ich die Angabe zur Collation? Ich glaube was mit utf8?

                        Schau in die Tabellendefinition, CREATE-Statement oder im Information_Schema.

                        • SHOW CREATE TABLE tbl_name
                        • SELECT collation_name FROM information_schema.columns WHERE table_schema='databasename' AND table_name='tablename' AND column_name='Title'

                        Lo!

                        1. SO ich habe folgendes festgestellt:

                          Es gibt in dieser Drupal-Installation folgende Funktion

                          function _db_query_callback($match, $init = FALSE) {  
                            static $args = NULL;  
                            if ($init) {  
                              $args = $match;  
                              return;  
                            }  
                            
                            switch ($match[1]) {  
                              case '%d': // We must use type casting to int to convert FALSE/NULL/(TRUE?)  
                                $value = array_shift($args);  
                                // Do we need special bigint handling?  
                                if ($value > PHP_INT_MAX) {  
                                  $precision = ini_get('precision');  
                                  @ini_set('precision', 16);  
                                  $value = sprintf('%.0f', $value);  
                                  @ini_set('precision', $precision);  
                                }  
                                else {  
                                  $value = (int) $value;  
                                }  
                                // We don't need db_escape_string as numbers are db-safe.  
                                return $value;  
                              case '%s':  
                                return db_escape_string(array_shift($args));  
                              case '%n':  
                                // Numeric values have arbitrary precision, so can't be treated as float.  
                                // is_numeric() allows hex values (0xFF), but they are not valid.  
                                $value = trim(array_shift($args));  
                                return is_numeric($value) && !preg_match('/x/i', $value) ? $value : '0';  
                              case '%%':  
                                return '%';  
                              case '%f':  
                                return (float) array_shift($args);  
                              case '%b': // binary data  
                                return db_encode_blob(array_shift($args));  
                            }  
                          }
                          

                          Diese Funktion wandelt den String "%film und utopie%" um in "0film und utopie%" und damit kann es kein Ergebnis geben. Bei Großschreibung passiert das nicht und bei vorliegen eines doppelten %% ebenfalls nicht, da nur das jeweils erste %-Zeichen entfernt wird.

                          Frage: wie verhindere ich das, denn die Funktion wird ja ihre Berechtigung haben? Warum wird "%f" umgewandelt?

                          1. Hi!

                            Es gibt in dieser Drupal-Installation folgende Funktion
                            [...]
                                case '%%':
                                  return '%';
                                case '%f':
                                  return (float) array_shift($args);
                            [...]

                            Na bitte, damit wird das Problem nachvollzieh- und erklärbar.

                            Diese Funktion wandelt den String "%film und utopie%" um in "0film und utopie%" und damit kann es kein Ergebnis geben. Bei Großschreibung passiert das nicht und bei vorliegen eines doppelten %% ebenfalls nicht, da nur das jeweils erste %-Zeichen entfernt wird.

                            Anhand des obigen Ausschnittes wirst du bemerken, dass %f und %% durch diese Funktion eine Sonderbehandlung erfährt. Wenn du dir mal allgemein die case-Zeilen ansiehst, wirst du noch einige andere Prozent-Kombinationen sehen, die ebenfalls zu Verwirrung führen.

                            Der %f-zu-0-Fall erklärt sich dadurch, dass in $args ein Argument erwartet wird, das da sicherlich nicht drinsteht. array_shift() liefert dann null, was durch den Typecast zu float zu 0 wird. Und statt des %% wird nur ein % zurückgegeben.

                            Frage: wie verhindere ich das, denn die Funktion wird ja ihre Berechtigung haben? Warum wird "%f" umgewandelt?

                            Diese Funktion hält also für einige Prozent-Kombinationen eine Sonderbehandlung bereit. Wenn du diese nicht haben möchtest, musst du %% notieren, wenn du exakt ein % an das DBMS schicken möchtest.

                            Lo!

                            1. Diese Funktion hält also für einige Prozent-Kombinationen eine Sonderbehandlung bereit. Wenn du diese nicht haben möchtest, musst du %% notieren, wenn du exakt ein % an das DBMS schicken möchtest.

                              erstmal danke und dann noch ein Frage;
                              Die Kombinationen mit % wofür stehen die? Was soll mit der Ausfilterung verhindert werden?

                              1. Hi!

                                Die Kombinationen mit % wofür stehen die? Was soll mit der Ausfilterung verhindert werden?

                                Es sind Platzhalter, analog/ähnlich zur schon mal erwähnten Funktion sprintf(). Und es ähnelt auch ein wenig dem Prepared-Statements-Prinzip. Ich kenne Drupal nicht, aber ich nehme an, die Philosophie ist, dass du Statements nicht durch Einfügen von Werten erstellen/erweitern/anpassen/wasauchimmer sollst, sondern Platzhalter gemäß dem Datentyp einbaust und die eigentlichen Werte per extra Parameter dazureichst. Ein Beispiel für die Verwendung von sprintf() findest du unter anderem im Kontextwechsel-Artikel. In deinem Fall brauchst du allerdings keine maskierten Parameter zu übergeben, denn um das kontextgerechte Behandeln der Typen kümmert sich die Funktion. Du müsstest nur ... LIKE '%s' einbauen und zusätzlich %Film und Utopie% übergeben. Dann sollte alles gut werden. Es kann allerdings auch sein, dass diese Funktion nicht nur maskiert sondern auch quotiert. Dann darf nur ... LIKE %s im Statement stehen. Das sollte aber die Dokumentation von Drupal hergeben, wie Datenbankzugriffe gedacht sind. Es ist sehr empfehlenswert, sich vor dem Ändern/Erweitern solcher Systeme sich in deren Philosophie einzuarbeiten, wie das Vorgehen bei solchen und anderen Standardaufgaben vorgesehen ist.

                                Lo!

                                1. Moin!

                                  Es ist sehr empfehlenswert, sich vor dem Ändern/Erweitern solcher Systeme sich in deren Philosophie einzuarbeiten, wie das Vorgehen bei solchen und anderen Standardaufgaben vorgesehen ist.

                                  Hier am Besten nix anfassen. Soweit ich weiss, wird diese Funktion von n anderen Drupalfunktionen benutzt.

                                  --
                                  Vergesst Chuck Norris.
                                  Sponge Bob kann unter Wasser grillen!
                                  1. Nein, werde es nicht anfassen, will es nur verstehen.

                                    Jedenfalls danke an alle, es wird reichen um weitermachen zu können.

                                  2. Hi!

                                    Es ist sehr empfehlenswert, sich vor dem Ändern/Erweitern solcher Systeme sich in deren Philosophie einzuarbeiten, wie das Vorgehen bei solchen und anderen Standardaufgaben vorgesehen ist.
                                    Hier am Besten nix anfassen. Soweit ich weiss, wird diese Funktion von n anderen Drupalfunktionen benutzt.

                                    Ja, vorhandenes Zeug sollte man nicht umschreiben, höchstens durch Plugins erweitern. Von einem solchen Szenario ging ich aus und vermutete, dass er beim Verwenden der vorhandenen Funktionen auf Probleme gestoßen ist.

                                    Lo!

                      2. Hallo,

                        bitte verstreue identische Postings nicht mehrfach im Thread. Das bringt nur ein heilloses Durcheinander und keinerlei Mehrwert.

                        Ich habe die Dubletten am Ende des Threads entsorgt, hier an dieser Stelle sind die Beiträge vom Diskussionsverlauf her sinnvoll untergebracht.

                        So long,
                         Martin

                        --
                        Theorie ist, wenn jeder weiß, wie's geht, und es geht trotzdem nicht.
                        Praxis ist, wenn's geht, und keiner weiß warum.
                        Bei uns sind Theorie und Praxis vereint: Nichts geht, und keiner weiß warum.
                        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                        1. T'schuldigung, aber ich komme mit diesem Forum noch nicht wirklich zurecht, sorry.

          2. Hi!

            Vielelicht haben GRandmasterA und ich ja hellseherische Faehigkeiten entwickelt. Aber

            SELECT 'Film und Utopie' LIKE '%Wert%', 'film und utopie' LIKE '%Wert%', 'Film und Utopie' LIKE '%%Wert%%', 'film und utopie' LIKE '%%Wert%%'
            hat er wohl auch nicht. Vielmehr duerfte das ungefaehr so aussehen:

            SELECT * FROM Filmdatenbank WHERE Titel LIKE '%Film und Utopie%' - liefert Daten
            SELECT * FROM Filmdatenbank WHERE Titel LIKE '%Film und utopie%' - liefert Daten
            SELECT * FROM Filmdatenbank WHERE Titel LIKE '%film und utopie%' - liefert nix
            SELECT * FROM Filmdatenbank WHERE Titel LIKE '%%film und utopie%%' - liefert Daten

            Laut Ausgangsposting hat er

            Wert in der Datenbank: "Film und Utopie"

            Aber selbst wenn dein Szenario zuträfe, wäre (mir) immer noch der Inhalt des Feldes Titel unbekannt. Und wenn der "Film und Utopie" oder "film und utopie" wäre, träfen alle 4 Kombinationen zu.

            Finde ich nachvollziehbar erlaeutert.

            Mir sind da zu viele "Interpretationsmöglichkeiten".

            Lo!

            1. Moin!

              Aber selbst wenn dein Szenario zuträfe, wäre (mir) immer noch der Inhalt des Feldes Titel unbekannt. Und wenn der "Film und Utopie" oder "film und utopie" wäre, träfen alle 4 Kombinationen zu.

              Es steht scheinbar 'Film und Utopie' drin. Und der OP wundert sich warum dann '%film und utopie%' nicht greift. Wenn das alles so zutrifft, ich mich uebrigens auch.

              --
              Vergesst Chuck Norris.
              Sponge Bob kann unter Wasser grillen!
              1. Hi,

                Es steht scheinbar 'Film und Utopie' drin. Und der OP wundert sich warum dann '%film und utopie%' nicht greift. Wenn das alles so zutrifft, ich mich uebrigens auch.

                Es liegt an der Collation, die hatte dedlfix doch eingangs schon erwähnt.

                A collation is a set of rules for comparing characters in a character set.

                Wenn die gewählte Collation nicht die Vergleichsaussage enthält, dass 'A' gleich 'a' angesehen werden soll, dann ergibt 'A' LIKE '%a%' auch keinen Treffer.

                MfG ChrisB

                --
                RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
                1. Ja.
                  Aber: 'U' ist ja angeblich auch gleich 'u'
                  Welche collation soll das denn sein?

                  --
                  Vergesst Chuck Norris.
                  Sponge Bob kann unter Wasser grillen!
                  1. Hi!

                    Aber: 'U' ist ja angeblich auch gleich 'u'
                    Welche collation soll das denn sein?

                    In allen Kollation, die auf _ci enden, wird nicht nach Groß-/Kleinschreibung unterschieden. Es gibt außerdem noch _bin und einige wenige, die auf _cs enden, aber letztere sind für unseren Kulturkreis nicht interessant. Dabei gehe ich von MySQL aus, denn welches DBMS der OP verwendet, hat er auch nicht genannt.

                    Lo!

                    1. In allen Kollation, die auf _ci enden, wird nicht nach Groß-/Kleinschreibung unterschieden. Es gibt außerdem noch _bin und einige wenige, die auf _cs enden, aber letztere sind für unseren Kulturkreis nicht interessant.

                      Eben. Deshalb sollte der Fehler ja eigentlich nicht auftreten. Der OP glaenzt im Moment aber ja durch Abwesenheit.

                      Dabei gehe ich von MySQL aus, denn welches DBMS der OP verwendet, hat er auch nicht genannt.

                      Das ist natuerlich korrekt. Ich gehe auch von mySQL aus.

                      --
                      Vergesst Chuck Norris.
                      Sponge Bob kann unter Wasser grillen!