¿Cómo se prepara correctamente una instrucción% LIKE% SQL?

34

Me gustaría usar una declaración LIKE% text% mientras sigo usando la clase $ wpdb de WordPress para desinfectar y preparar la entrada.

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

He intentado algo como esto en vano:

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

¿Cómo se prepara correctamente una instrucción% LIKE% SQL utilizando la clase de base de datos de WordPress?

editor
fuente

Respuestas:

49

La $wpdb->esc_likefunción existe en WordPress porque el escape regular de la base de datos no se escapa %y los _caracteres. Esto significa que puede agregarlos en sus argumentos wpdb::prepare()sin problemas. Esto también es lo que veo en el código central de WordPress :

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

Entonces su código se vería así:

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

También puede agregar %%su consulta para obtener un literal %( wpdb::prepare()usos vsprintf()en segundo plano, que tiene esta sintaxis ), pero recuerde que su cadena no se citará , debe agregar las citas usted mismo (que no es lo que generalmente tiene que hacer en wpdb::prepare().

Jan Fabry
fuente
¿cuáles son los {}para?
Francisco Corrales Morales
@FranciscoCorralesMorales: para indicar que todo lo que contiene debe considerarse una expresión variable , de lo contrario, solo vería $wpdbe ignoraría el ->prefixsiguiente.
Jan Fabry
1
@ JanFabry Cerrar. Corregiría el comentario para decir: "... de lo contrario vería todo $wpdb->base_prefixmy_tablee intentaría buscar la base_prefixmy_tablepropiedad en lugar de solo base_prefix."
Flimm
3

Debe duplicar el porcentaje para que no sean tratados como marcadores de fragmentos por 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));

PD: no estoy seguro de que esta sea la mejor / única forma de hacerlo.

Rarst
fuente
44
Recuerde que debe agregar las comillas alrededor de la cadena usted mismo , ya wpdb::prepareque solo las agregará para un %sque no esté precedido por un% . La parte final de su consulta debería ser WHERE column_2 LIKE '%%%s%%'.
Jan Fabry
2

Esta es una forma de hacerlo que he comprobado y funciona:

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

Reemplace las variables para satisfacer sus necesidades.

Calvin
fuente
55
Deberías escapar de los %caracteres (mediante el uso like_escape(). Ver: codex.wordpress.org/Class_Reference/…
Stephen Harris