Utilizzare un UDT SQLCLR. Ciò potrebbe funzionare, sebbene non sia chiaro se presenti un guadagno netto rispetto all'approccio sopra descritto.
Sì, un SQLCLR UDT può far sovrascrivere i suoi operatori di confronto con algoritmi personalizzati. Gestisce situazioni in cui il valore viene confrontato con un altro valore che è già lo stesso tipo personalizzato o che deve essere convertito implicitamente. Questo dovrebbe gestire il filtro intervallo in una WHERE
condizione.
Per quanto riguarda l'ordinamento dell'UDT come un normale tipo di colonna (non una colonna calcolata), ciò è possibile solo se l'UDT è "byte ordinato". Essere "byte ordinati" significa che la rappresentazione binaria dell'UDT (che può essere definita nell'UDT) ordina naturalmente nell'ordine appropriato. Supponendo che la rappresentazione binaria sia gestita in modo simile all'approccio sopra descritto per la colonna VARCHAR (50) che ha segmenti a lunghezza fissa che sono riempiti, che si qualificherebbe. Oppure, se non fosse facile garantire che la rappresentazione binaria fosse naturalmente ordinata nel modo corretto, è possibile esporre un metodo o una proprietà dell'UDT che genera un valore che sarebbe correttamente ordinato e quindi creare una PERSISTED
colonna calcolata su tale metodo o proprietà. Il metodo deve essere deterministico e contrassegnato come IsDeterministic = true
.
I vantaggi di questo approccio sono:
- Non è necessario un campo "valore originale".
- Non è necessario chiamare un UDF per inserire i dati o confrontare i valori. Supponendo che il
Parse
metodo dell'UDT assuma il P7B18
valore e lo converta, allora dovresti essere in grado di inserire semplicemente i valori come P7B18
. E con il metodo di conversione implicita impostato nell'UDT, la condizione WHERE consentirebbe anche di utilizzare semplicemente P7B18`.
Le conseguenze di questo approccio sono:
- La semplice selezione del campo restituirà la rappresentazione binaria, se si utilizza l'UDT ordinato dal byte come tipo di dati della colonna. O se si utilizza una
PERSISTED
colonna calcolata su una proprietà o un metodo dell'UDT, si otterrà la rappresentazione restituita dalla proprietà o dal metodo. Se si desidera il P7B18
valore originale , è necessario chiamare un metodo o una proprietà dell'UDT codificata per restituire tale rappresentazione. Dal momento che è necessario ignorare il ToString
metodo comunque, questo è un buon candidato per fornire questo.
Non è chiaro (almeno per me in questo momento poiché non ho testato questa parte) quanto sia facile / difficile apportare modifiche alla rappresentazione binaria. La modifica della rappresentazione memorizzabile e ordinabile potrebbe richiedere l'abbandono e l'aggiunta del campo. Inoltre, la caduta dell'Assemblea contenente l'UDT fallirebbe se utilizzata in entrambi i modi, quindi si dovrebbe assicurarsi che non ci fosse nient'altro nell'Assemblea oltre a questo UDT. Puoi ALTER ASSEMBLY
sostituire la definizione, ma ci sono alcune restrizioni a riguardo.
D'altra parte, il VARCHAR()
campo è costituito da dati che sono disconnessi dall'algoritmo, quindi richiederebbe solo l'aggiornamento della colonna. E se ci sono decine di milioni di righe (o più), ciò può essere fatto in un approccio discontinuo.
Implementare la libreria ICU che in realtà consente di eseguire questo ordinamento alfanumerico. Sebbene altamente funzionale, la libreria è disponibile solo in due lingue: C / C ++ e Java. Ciò significa che potrebbe essere necessario apportare alcune modifiche per farlo funzionare in Visual C ++ o c'è la possibilità che il codice Java possa essere convertito in MSIL usando IKVM . Esistono uno o due progetti lato .NET collegati su quel sito che forniscono un'interfaccia COM a cui è possibile accedere nel codice gestito, ma credo che non siano stati aggiornati da un po 'e non li ho provati. La scommessa migliore qui sarebbe quella di gestirla nel livello dell'app con l'obiettivo di generare chiavi di ordinamento. Le chiavi di ordinamento verrebbero quindi salvate in una nuova colonna di ordinamento.
Questo potrebbe non essere l'approccio più pratico. Tuttavia, è ancora molto bello che esista una tale abilità. Ho fornito una guida più dettagliata di un esempio di questo nella seguente risposta:
Esiste un confronto per ordinare le seguenti stringhe nel seguente ordine 1,2,3,6,10,10A, 10B, 11?
Ma il modello trattato in quella domanda è un po 'più semplice. Per un esempio che mostra che il tipo di modello trattato in questa domanda funziona anche, vai alla pagina seguente:
Demo di confronto ICU
In "Impostazioni", imposta l'opzione "numerica" su "on" e tutti gli altri dovrebbero essere impostati su "default". Successivamente, a destra del pulsante "ordina", deseleziona l'opzione per "punti di forza diff" e controlla l'opzione per "ordina chiavi". Quindi sostituire l'elenco di elementi nell'area di testo "Input" con il seguente elenco:
P12B22
P7B18
P12B3
as456456hgjg6786867
P7Bb19
P7BA19
P7BB19
P007B18
P7Bb20
P7Bb19z23
Fai clic sul pulsante "ordina". L'area di testo "Output" dovrebbe visualizzare quanto segue:
as456456hgjg6786867
29 4D 0F 7A EA C8 37 35 3B 35 0F 84 17 A7 0F 93 90 , 0D , , 0D .
P7B18
47 0F 09 2B 0F 14 , 08 , FD F1 , DC C5 DC 05 .
P007B18
47 0F 09 2B 0F 14 , 08 , FD F1 , DC C5 DC 05 .
P7BA19
47 0F 09 2B 29 0F 15 , 09 , FD FF 10 , DC C5 DC DC 05 .
P7Bb19
47 0F 09 2B 2B 0F 15 , 09 , FD F2 , DC C5 DC 06 .
P7BB19
47 0F 09 2B 2B 0F 15 , 09 , FD FF 10 , DC C5 DC DC 05 .
P7Bb19z23
47 0F 09 2B 2B 0F 15 5B 0F 19 , 0B , FD F4 , DC C5 DC 08 .
P7Bb20
47 0F 09 2B 2B 0F 16 , 09 , FD F2 , DC C5 DC 06 .
P12B3
47 0F 0E 2B 0F 05 , 08 , FD F1 , DC C5 DC 05 .
P12B22
47 0F 0E 2B 0F 18 , 08 , FD F1 , DC C5 DC 05 .
Le chiavi di ordinamento sono strutturate in più campi, separate da virgole. Ogni campo deve essere ordinato in modo indipendente, in modo che presenti un altro piccolo problema da risolvere se è necessario implementarlo in SQL Server.
P7B12
potrebbe diventareP 07 B 12
, quindi (tramite ASCII)80 07 65 12
, quindi80076512