2009-01-11 12 views
6

Quiero ser capaz de pasar algo a una consulta SQL para determinar si quiero seleccionar solo aquellos en los que cierta columna es nula. Si sólo estaba construyendo una cadena de consulta en lugar de utilizar variables ligadas, que haría algo como:¿Cómo puedo seleccionar las filas que son nulas usando consultas enlazadas en DBI de Perl?

if ($search_undeleted_only) 
{ 
    $sqlString .= " AND deleted_on IS NULL"; 
} 

pero quiero utilizar consultas consolidados. ¿Esta sería la mejor manera?

my $stmt = $dbh->prepare(... 
    "AND (? = 0 OR deleted_on IS NULL) "); 
$stmt->execute($search_undeleted_only); 

Respuesta

4

Sí; un truco relacionado es que si tiene X filtros potenciales, algunos de ellos opcionales, debe tener la plantilla que diga " AND (?=-1 OR some_field = ?) ", y cree una función especial que envuelva la llamada de ejecución y vincule todos los segundos. (en este caso, -1 es un valor especial que significa 'ignorar este filtro').

Actualización de Paul Tomblin: Edité la respuesta para incluir una sugerencia de los comentarios.

+0

Eso está bien, pero póngalo al revés (la? = - 1 parte primero), ya que muchas bases de datos SQL donde las cláusulas cortocircuitan (es decir, no molestará evaluar la parte posterior de una instrucción O si la primera parte es verdadera ya que no hay manera de que evalúe a nada más que cierto). –

+0

Robert tiene razón, '? = - 1' debería ir primero – SquareCog

+0

Espero que no les importe, pero voy a editar su respuesta para poner el? = - 1 primero solo para mejorar la respuesta. –

1

Creo que es un enfoque razonable. Sigue muy bien el patrón de filtro normal y debería proporcionar un buen rendimiento.

2

¿Estás confiando en un cortocircuito en la semántica de expresiones booleanas para invocar tu condición IS NULL? Eso parece funcionar.

Un punto interesante es que el optimizador de consultas debe tener en cuenta una expresión constante como 1 = 0 que no tenía parámetros. En este caso, dado que el optimizador no sabe si la expresión es una constante true o false hasta el tiempo de ejecución, eso significa que no puede factorizarlo. Debe evaluar la expresión de cada fila.

Por lo tanto, se puede suponer que esto agrega un costo menor a la consulta, en relación con lo que costaría si hubiera utilizado una expresión constante no parametrizada.

Luego combinar con OR con la expresión IS NULL también puede tener implicaciones para el optimizador. Puede decidir que no puede beneficiarse de un índice en deleted_on, mientras que en una expresión más simple lo tendría. Esto depende de la implementación de RDBMS que esté utilizando y de la distribución de valores en su base de datos.

+0

@Bill, esa es realmente una gran información sobre la optimización de la consulta, y me gustaría poder aceptar tanto las respuestas tuyas como las de Dmitriy. –

+0

¡Sin preocupaciones! Me alegra que haya sido útil. –

Cuestiones relacionadas