Jak właściwie przygotować instrukcję SQL% LIKE%?

34

Chciałbym użyć instrukcji LIKE% text%, wciąż używając klasy WordPress $ wpdb do dezynfekcji i przygotowywania danych wejściowych.

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

Próbowałem czegoś takiego bezskutecznie:

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

Jak poprawnie przygotować instrukcję SQL% LIKE% przy użyciu klasy bazy danych WordPress?

redaktor
źródło

Odpowiedzi:

49

$wpdb->esc_likeFunkcja istnieje w WordPress ponieważ regularny wyciek bazy danych nie uciec %i _znaki. Oznacza to, że możesz wpdb::prepare()bez problemu dodawać je do swoich argumentów . To też widzę w podstawowym kodzie WordPress :

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

Twój kod wyglądałby następująco:

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

Możesz również dodać %%w zapytaniu, aby uzyskać literał %( wpdb::prepare()używa vsprintf()w tle, który ma tę składnię ), ale pamiętaj, że łańcuch nie będzie cytowany , musisz sam dodać cytaty (co nie jest zwykle tym, co musisz zrobić w wpdb::prepare().

Jan Fabry
źródło
co to są {}za?
Francisco Corrales Morales,
@FranciscoCorralesMorales: Aby wskazać, że wszystko w nim powinno być traktowane jako wyrażenie zmienne , w przeciwnym razie zobaczy tylko $wpdbi zignoruje ->prefixpo nim.
Jan Fabry
1
@JanFabry Zamknij. $wpdb->base_prefixmy_tablebase_prefixmy_tablebase_prefix
Poprawiłbym
3

Musisz podwoić procent, aby nie były traktowane jak markery fragmentów przez 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 nie jestem pewien, czy jest to najlepszy / jedyny sposób, aby to zrobić.

Rarst
źródło
4
Pamiętaj, że musisz sam dodać cudzysłowy wokół ciągu , ponieważ wpdb::preparedodasz je tylko dla %sznaku, który nie jest poprzedzony znakiem% . Ostatnią częścią twojego zapytania powinno być WHERE column_2 LIKE '%%%s%%'.
Jan Fabry,
2

Jest to jeden ze sposobów, aby to sprawdzić, i sprawdziłem:

$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 
    ) 
);

Zamień zmienne zgodnie z własnymi potrzebami.

Calvin
źródło
5
Powinieneś unikać %znaków (używając like_escape(). Patrz: codex.wordpress.org/Class_Reference/…
Stephen Harris