Pregunta

Al crear mi base de datos SQLite en Android que establece la configuración regional de base de datos - db.setLocale (nueva configuración regional ( "cz_CZ")). Esta es una configuración regional Checa.

Fábrica de instrucción SELECT y toma la configuración regional en cuenta, por ejemplo:

SELECT * from table WHERE name='sctzy' COLLATE LOCALIZED 

encontrará la entrada 'šctžý'.

Sin embargo, utilizando como fallará:

SELECT * from table WHERE name LIKE '%sctzy%' COLLATE LOCALIZED 

No se devuelve la fila.

Por cierto. No hay ninguna clase java.text.Normalized en Android. Pensé que podría hacer una segunda columna con un texto normalizado, despojado de caracteres especiales, que se utiliza para buscar - pero me falta una clase o forma de cómo normalizar la cadena

.

Otros consejos

Creación de una segunda columna normalizada se puede usar para ir alrededor de limitaciones (como se ha mencionado brevemente en otras respuestas).

Esto significa en la práctica que hay que crear otra (sombra) de su primera columna, donde se almacenan los mismos datos en un caso fijo (por ejemplo, todos los caracteres superiores). Caso consultas insensibles (incluyendo como consultas) se pueden hacer en esta nueva columna con los valores de búsqueda en el mismo caso.

Si la primera columna "a" contiene
AAA
AAA
Bbb
AAA
eee
La segunda columna a_shadow contendría por las mismas filas
AAA
AAA
acreditación
AAA
eee

y su búsqueda original (ejemplo) "seleccionar una de mitabla donde a = 'AAA'"
sería reemplazado con "seleccione una de mitabla donde A = 'AAA'"

Su código debe ser actualizado para llenar el contenido sombra convertida al agregar el contenido principal. Si se añade la columna después de la creación o no se puede cambiar el código de valores existentes pueden necesitar ser convertidos mediante una consulta de actualización. Ejemplo:

UPDATE mytable SET a_shadow=UPPER(a);

Hoy mismo he tenido exactamente la misma tarea que tenías. Y en mi situación haciendo sombra columnas adicionales que no es un caso porque yo estoy teniendo que buscar más de una columna. Así que llegué a la solución de este tipo, que se probó en proyecto real. En mi caso yo estoy manejando sólo letras minúsculas, pero se puede extender la función con letras mayúsculas también.

db.setLocale(Locale("cz", "CZ"))
val query = "SELECT * FROM table WHERE name GLOB ${getExpr(str)} ORDER BY name COLLATE LOCALIZED ASC"

private fun getExpr(input: String) : String{
    var expr = ""
    for(lettter in input){
        expr += when(lettter){
            's','š' -> "[sš]"
            'a','á' -> "[aá]"
            'e','ě','é' -> "[eěé]"
            'i','í' -> "[ií]"
            'z','ž' -> "[zž]"
            'c','č' -> "[cč]"
            'y','ý' -> "[yý]"
            'r','ř' -> "[rř]"
            'u','ů','ú' -> "[uůú]"
            'o','ó' -> "[oó]"
            'n','ň' -> "[nň]"
            'd','ď' -> "[dď]"
            't','ť' -> "[tť]"
            else -> lettter
        }
     }
     return "'*${expr}*'"
}

Podría llevar mucho tiempo, pero se puede utilizar el java.text.Normalizer como aquí

conversión de símbolos, Accent Cartas al alfabeto Inglés

Como no es parte del subconjunto de Java que Android, se puede tratar de buscar que el código de Java, como Normalizer.java Con el Javadoc encontrado aquí :

Y copiar parte del código necesario dentro de su proyecto.

Esperanza funciona!

SQLite En Android, LIKE y GLOB ignoran tanto COLLATE LOCALIZED y COLLATE UNICODE (sólo trabajo para ORDER BY). Sin embargo, como se explica en @asat su respuesta , puede utilizar GLOB con un patrón que reemplazará a cada letra con todos los disponibles alternativas de esa carta. En Java:

public static String addTildeOptions(String searchText) {
    return searchText.toLowerCase()
                     .replaceAll("[aáàäâã]", "\\[aáàäâã\\]")
                     .replaceAll("[eéèëê]", "\\[eéèëê\\]")
                     .replaceAll("[iíìî]", "\\[iíìî\\]")
                     .replaceAll("[oóòöôõ]", "\\[oóòöôõ\\]")
                     .replaceAll("[uúùüû]", "\\[uúùüû\\]")
                     .replace("*", "[*]")
                     .replace("?", "[?]");
}

Y luego (no literalmente como este, por supuesto):

SELECT * from table WHERE lower(column) GLOB "*addTildeOptions(searchText)*"

De esta manera, por ejemplo, en español, una búsqueda del usuario, ya sea para mas o Más obtendrá la búsqueda convertida en m [aaaaaa] s , volviendo ambos resultados.

Es importante notar que ignora GLOB COLLATE NOCASE, por eso me convertí todo a minúsculas tanto en la función y en la consulta. Nótese también que la función lower() en sqlite no funciona en caracteres no ASCII - pero de nuevo esos son probablemente los que ya se está reemplazando

La función también reemplaza los dos comodines GLOB, * y ?, con versiones "escapado".

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