Domanda

Devo aggiungere la possibilità per gli utenti del mio software di selezionare i record per intervalli di caratteri.
Come posso scrivere una query che restituisce tutti i widget da una tabella il cui nome rientra nell'intervallo Ba-Bi per esempio?

Attualmente sto usando un maggiore o minore di operatori, quindi l'esempio sopra diventerebbe:

select * from widget
where name >= 'ba' and name < 'bj'

Nota come ho " incrementato " l'ultimo carattere del limite superiore da i a j in modo che " bike " non sarebbe lasciato fuori.

Esiste un modo generico per trovare il personaggio successivo dopo un determinato personaggio in base alle regole di confronto del campo o sarebbe più sicuro creare una seconda condizione?

select * from widget
where name >= 'ba'
and (name < 'bi' or name like 'bi%')

La mia applicazione deve supportare la localizzazione. Quanto è sensibile questo tipo di query a diversi set di caratteri?

Devo anche supportare sia MSSQL che Oracle. Quali sono le mie opzioni per garantire che il carattere sia ignorato indipendentemente dalla lingua visualizzata nei dati?

È stato utile?

Soluzione

Passiamo direttamente alla localizzazione. Diresti & Quot; aa & Quot; > = " ba " ? Probabilmente no, ma è lì che si ordina in Svezia. Inoltre, semplicemente non puoi presumere che puoi ignorare il case in qualsiasi lingua. Il case è esplicitamente dipendente dalla lingua, con l'esempio più comune è il turco: maiuscolo i è & # 304 ;. La I minuscola è & # 305 ;.

Ora, il tuo DB SQL definisce il risultato di < ;, == etc con un " ordine di confronto " ;. Questo è decisamente specifico per la lingua. Quindi, dovresti controllare esplicitamente questo, per ogni query. Un ordine di confronto turco metterà quelli i cui appartengono (in turco). Non puoi fare affidamento sulle regole di confronto predefinite.

Come per la " parte incrementale! " ;, non preoccuparti. Attenersi a & Gt; = e & Lt; =.

Altri suggerimenti

Per MSSQL vedere questa discussione: http://bytes.com/forum/thread483570.html.

Per Oracle, dipende dalla versione di Oracle, in quanto Oracle 10 ora supporta regex (p) come le query: http://www.psoug.org/reference/regexp.html (cerca regexp_like) e leggi questo articolo: http://www.oracle.com/technology/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html

HTH

Frustrantemente, la funzione di sottostringa Oracle è SUBSTR (), mentre SQL Server è SUBSTRING ().

Potresti scrivere un semplice wrapper attorno a uno o entrambi in modo che condividano lo stesso nome funzione + prototipo.

Quindi puoi semplicemente usare

MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'

o simile.

Potresti usare questo ...

select * from widget
where name Like 'b[a-i]%'

Corrisponderà a qualsiasi riga in cui il nome inizia con b, il secondo carattere è compreso nell'intervallo da a a i e tutti gli altri caratteri seguono.

Penso che andrei con qualcosa di semplice come aggiungere una stringa di alto ordinamento alla fine del limite superiore. Qualcosa del tipo:

select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'

Non sono sicuro che sarebbe sopravvissuto alla conversione EBCDIC però

Potresti anche farlo in questo modo:

select * from widget
where left(name, 2) between 'ba' and 'bi'

Se la lunghezza dei criteri cambia (come sembrava indicare in un commento che hai lasciato), la query dovrebbe avere anche la lunghezza come input:

declare @CriteriaLength int
set @CriteriaLength = 4
select * from widget
where left(name, @CriteriaLength) between 'baaa' and 'bike'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top