Pregunta

Estoy ejecutando una base de datos MySQL localmente para el desarrollo, pero implementando en Heroku que usa Postgres. Heroku se encarga de casi todo, pero mis declaraciones Me gusta no son sensibles a mayúsculas. Podría usar sentencias de iLike, pero mi base de datos MySQL local no puede manejar eso.

¿Cuál es la mejor manera de escribir una consulta que no distinga mayúsculas y minúsculas que sea compatible con MySQL y Postgres? ¿O necesito escribir declaraciones Me gusta e iLike separadas dependiendo de la base de datos con la que está hablando mi aplicación?

¿Fue útil?

Solución

select * from foo where upper(bar) = upper(?);

Si configura el parámetro en mayúsculas en la persona que llama, puede evitar la segunda llamada de función.

Otros consejos

La moraleja de esta historia es: no utilice una pila de software diferente para el desarrollo y la producción. Nunca.

Simplemente terminarás con errores que no puedes reproducir en dev; Tu prueba no tendrá ningún valor. Simplemente no lo hagas.

El uso de un motor de base de datos diferente está fuera de discusión. Habrá MUCHOS casos en los que se comporte de manera diferente a LIKE (también, ¿ha revisado las intercalaciones en uso por las bases de datos? ¿Son idénticas en CADA CASO? Si no , puedes olvidarte de ORDER BY en las columnas varchar que funcionan de la misma manera)

Usa Arel:

Author.where(Author.arel_table[:name].matches("%foo%"))

match utilizará el operador ILIKE para Postgres, y LIKE para todo lo demás.

En postgres, puedes hacer esto:

SELECT whatever FROM mytable WHERE something ILIKE 'match this';

No estoy seguro de si hay un equivalente para MySQL, pero siempre puedes hacer esto, que es un poco feo, pero debería funcionar tanto en MySQL como en postgres:

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');

Hay varias respuestas, ninguna de las cuales es muy satisfactoria.

  • LOWER (barra) = LOWER (?) funcionará en MySQL y Postgres, pero es probable que se desempeñe terriblemente en MySQL : MySQL no utilizará sus índices debido a la función INFERIOR. En Postgres puede agregar un índice funcional (en LOWER (barra) ) pero MySQL no lo admite.
  • MySQL lo hará (a menos que haya configurado una intercalación ). haga una coincidencia que no distinga mayúsculas de minúsculas y utilice sus índices. ( barra =? ).
  • Desde su código fuera de la base de datos, mantenga los campos barra y bar_lower , donde bar_lower contiene el resultado de inferior (barra) . (Esto también puede ser posible utilizando activadores de base de datos). (Consulte el análisis de esta solución en Drupal ). Esto es torpe, pero al menos se ejecuta de la misma manera en casi todas las bases de datos.

REGEXP no distingue entre mayúsculas y minúsculas (a menos que se use con BINARY), y se puede usar, así ...

    SELECT id FROM person WHERE name REGEXP 'john';

... para que coincida con 'John', 'JOHN', 'john', etc.

Si está utilizando PostgreSQL 8.4, puede usar el citext módulo para crear campos de texto que no distinguen entre mayúsculas y minúsculas.

También puede considerar revisar el complemento searchlogic , que hace LIKE / ILIKE para usted.

También puede usar ~ * en postgres si desea hacer coincidir una subcadena dentro de un bloque. ~ coincide con subcadena sensible a mayúsculas y minúsculas, ~ * subcadena insensible a mayúsculas Es una operación lenta, pero podría ser útil para las búsquedas.

Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';

Ambos golpearían en " Un poco de texto desigual aquí " Solo el primero podría hacer clic en " algún texto inédito aquí "

La conversión a upper es mejor, ya que cubre la sintaxis compatible para los 3 backends de base de datos de Rails más utilizados. PostgreSQL, MySQL y SQLite soportan esta sintaxis. Tiene el inconveniente (menor) de que debe escribir en mayúsculas su cadena de búsqueda en su aplicación o en su cadena de condiciones, lo que lo hace un poco más feo, pero creo que la compatibilidad que obtiene hace que valga la pena.

Tanto MySQL como SQLite3 tienen un operador LIKE que no distingue entre mayúsculas y minúsculas. Solo PostgreSQL tiene un operador LIKE que distingue entre mayúsculas y minúsculas y un operador ILIKE específico para PostgreSQL (según el manual) para búsquedas que no distinguen entre mayúsculas y minúsculas. Puede especificar ILIKE en lugar de LIKE en sus condiciones en la aplicación Rails, pero tenga en cuenta que la aplicación dejará de funcionar bajo MySQL o SQLite.

Una tercera opción podría ser verificar qué motor de base de datos está utilizando y modificar la cadena de búsqueda en consecuencia. Esto podría hacerse mejor hackeando los adaptadores de conexión de ActiveRecord de / monkeypatching y haga que el adaptador PostgreSQL modifique la cadena de consulta para sustituir " LIKE " para " ILIKE " antes de la ejecución de la consulta. Sin embargo, esta solución es la más complicada y, a la luz de formas más sencillas, como el uso de ambos términos, creo que no es el esfuerzo (aunque obtendría muchos puntos brownie por hacerlo de esta manera).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top