Wie bereiten Sie eine% LIKE% SQL-Anweisung richtig vor?

34

Ich möchte eine LIKE% text% -Anweisung verwenden, während ich weiterhin die WordPress $ wpdb-Klasse verwende, um Eingaben zu bereinigen und vorzubereiten.

SELECT column_1 from `prefix_my_table` WHERE column_2 LIKE '%something%';

Ich habe so etwas ohne Erfolg versucht:

$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %s;", like_escape($number_to_put_in_like));

Wie bereiten Sie eine% LIKE% SQL-Anweisung mit der WordPress-Datenbankklasse richtig vor?

Editor
quelle

Antworten:

49

Die $wpdb->esc_likeFunktion ist in WordPress vorhanden, da die reguläre Escape-Funktion für Datenbanken %und _Zeichen nicht vorhanden ist. Dies bedeutet, dass Sie sie wpdb::prepare()problemlos in Ihre Argumente einfügen können. Das sehe ich auch im WordPress-Kerncode :

$wpdb->prepare(" AND $wpdb->usermeta.meta_key = '{$wpdb->prefix}capabilities' AND $wpdb->usermeta.meta_value LIKE %s", '%' . $this->role . '%');

Ihr Code würde also so aussehen:

$wpdb->prepare(
    "SELECT
        column_1
    FROM
        `{$wpdb->base_prefix}my_table`
    WHERE
        column_2 LIKE %s;",
    '%' . $wpdb->esc_like($number_to_put_in_like) . '%'
);

Sie können %%Ihrer Abfrage auch ein Literal hinzufügen %( wpdb::prepare()wird vsprintf()im Hintergrund verwendet und hat diese Syntax ). Beachten Sie jedoch, dass Ihre Zeichenfolge nicht in Anführungszeichen gesetzt wird. Sie müssen die Anführungszeichen selbst hinzufügen (was normalerweise nicht erforderlich ist) wpdb::prepare().

Jan Fabry
quelle
wofür sind die {}?
Francisco Corrales Morales
@FranciscoCorralesMorales: Um anzuzeigen, dass alles, was sich darin befindet, als variabler Ausdruck betrachtet werden soll , andernfalls wird nur der nachfolgende Ausdruck angezeigt $wpdbund ignoriert ->prefix.
Jan Fabry
1
@ JanFabry Schließen. Ich würde den Kommentar korrigieren, um zu sagen: "... ansonsten würde es alles sehen $wpdb->base_prefixmy_tableund versuchen, base_prefixmy_tableEigentum nachzuschlagen, anstatt nur base_prefix.
Flimm
3

Sie müssen Prozent verdoppeln, damit sie nicht wie Fragmentmarkierungen behandelt werden, indem Sie wpdb->prepare():

$wpdb->prepare( "SELECT column_1 from `{$wpdb->base_prefix}my_table` WHERE column_2 LIKE %%%s%%;", $wpdb->esc_like( $number_to_put_in_like));

PS nicht sicher, ob dies der beste / einzige Weg ist, es zu tun.

Rarst
quelle
4
Denken Sie daran, dass Sie die Anführungszeichen um die Zeichenfolge selbst hinzufügen müssen , da wpdb::preparesie nur für ein %sZeichen ohne vorangestelltes %Zeichen hinzugefügt werden . Der letzte Teil Ihrer Anfrage sollte sein WHERE column_2 LIKE '%%%s%%'.
Jan Fabry
2

Dies ist eine Möglichkeit, die ich überprüft habe und die funktioniert:

$search_text = "%" . $_GET['some_text'] . "%";

$user_count = $wpdb->get_var( 
    $wpdb->prepare( 
        "SELECT COUNT(*) FROM mix_library WHERE ml_setting_name LIKE %s", 
        $search_text 
    ) 
);

Ersetzen Sie die Variablen entsprechend Ihren Anforderungen.

Calvin
quelle
5
Sie sollten %Zeichen entkommen (mit like_escape(). Siehe: codex.wordpress.org/Class_Reference/…
Stephen Harris