Użyj SQLCLR UDT. Może to zadziałać, choć nie jest jasne, czy wykazuje zysk netto w porównaniu z podejściem opisanym powyżej.
Tak, SQLCLR UDT może zostać zastąpiony przez operatory porównania niestandardowymi algorytmami. Obsługuje to sytuacje, w których wartość jest porównywana z inną wartością, która jest już tego samego typu niestandardowego, lub taką, która wymaga niejawnej konwersji. To powinno obsłużyć filtr zakresu w określonych WHERE
warunkach.
W odniesieniu do sortowania UDT jako zwykłego typu kolumny (nie kolumny obliczanej), jest to możliwe tylko wtedy, gdy UDT jest „uporządkowane bajtowo”. Bycie „uporządkowanym w bajtach” oznacza, że binarna reprezentacja UDT (którą można zdefiniować w UDT) naturalnie sortuje się w odpowiedniej kolejności. Zakładając, że reprezentacja binarna jest obsługiwana podobnie do podejścia opisanego powyżej dla kolumny VARCHAR (50), która ma segmenty o stałej długości, które są wypełnione, to kwalifikuje się. Lub, jeśli nie było łatwo zapewnić, że reprezentacja binarna zostanie naturalnie uporządkowana we właściwy sposób, możesz ujawnić metodę lub właściwość UDT, która generuje wartość, która byłaby odpowiednio uporządkowana, a następnie utworzyć PERSISTED
na tej podstawie kolumnę obliczeniową metoda lub właściwość. Metoda musi być deterministyczna i oznaczona jako IsDeterministic = true
.
Korzyści z tego podejścia to:
- Nie ma potrzeby stosowania pola „pierwotna wartość”.
- Nie trzeba dzwonić do UDF, aby wstawić dane lub porównać wartości. Zakładając, że
Parse
metoda UDT przyjmuje P7B18
wartość i konwertuje ją, powinieneś być w stanie po prostu wstawić wartości naturalnie jako P7B18
. A przy metodzie domyślnej konwersji ustawionej w UDT warunek GDZIE pozwoliłby również na użycie po prostu P7B18`.
Konsekwencje tego podejścia są następujące:
- Po prostu wybranie pola zwróci reprezentację binarną, jeśli użyjesz bajtu UDT uporządkowanego jako typ danych kolumny. Lub jeśli używasz
PERSISTED
kolumny obliczeniowej we właściwości lub metodzie UDT, wówczas zwracana jest reprezentacja przez właściwość lub metodę. Jeśli chcesz oryginalną P7B18
wartość, musisz wywołać metodę lub właściwość UDT, która jest zakodowana, aby zwrócić tę reprezentację. Ponieważ i tak musisz przesłonić tę ToString
metodę, jest to dobry kandydat do tego.
Nie jest jasne (przynajmniej dla mnie teraz, ponieważ nie przetestowałem tej części), jak łatwo / trudno byłoby wprowadzić zmiany w reprezentacji binarnej. Zmiana zapisanej reprezentacji sortowalnej może wymagać usunięcia i ponownego dodania pola. Ponadto upuszczenie zestawu zawierającego UDT nie powiedzie się, jeśli zostanie użyty w jakikolwiek sposób, dlatego należy upewnić się, że poza tym UDT nie ma nic innego w zestawie. Możesz ALTER ASSEMBLY
zastąpić definicję, ale istnieją pewne ograniczenia.
Z drugiej strony, VARCHAR()
pole to dane, które są odłączone od algorytmu, więc wymagałoby jedynie aktualizacji kolumny. A jeśli są dziesiątki milionów wierszy (lub więcej), można to zrobić w trybie wsadowym.
Zaimplementuj bibliotekę ICU, która faktycznie umożliwia przeprowadzanie tego sortowania alfanumerycznego. Choć wysoce funkcjonalna, biblioteka jest dostępna tylko w dwóch językach: C / C ++ i Java. Co oznacza, że możesz potrzebować kilku poprawek, aby działało w Visual C ++, lub istnieje szansa, że kod Java można przekonwertować na MSIL przy użyciu IKVM . Na tej stronie znajduje się jeden lub dwa projekty poboczne .NET, które zapewniają interfejs COM, do którego można uzyskać dostęp w kodzie zarządzanym, ale wierzę, że od jakiegoś czasu nie były aktualizowane i nie próbowałem ich. Najlepszym rozwiązaniem byłoby poradzenie sobie z tym w warstwie aplikacji w celu wygenerowania kluczy sortowania. Klucze sortowania zostaną następnie zapisane w nowej kolumnie sortowania.
To może nie być najbardziej praktyczne podejście. Jednak nadal jest bardzo fajnie, że taka zdolność istnieje. Bardziej szczegółowy opis tego przykładu podałem w następującej odpowiedzi:
Czy istnieje sortowanie do sortowania następujących ciągów w następującej kolejności 1,2,3,6,10,10A, 10B, 11?
Ale wzorzec omawiany w tym pytaniu jest nieco prostszy. Aby zobaczyć przykład pokazujący, że rodzaj wzorca opisanego w tym pytaniu również działa, przejdź do następującej strony:
ICU Collation Demo
W „Ustawieniach” ustaw opcję „numeryczne” na „włączone”, a wszystkie pozostałe powinny być ustawione na „domyślne”. Następnie, po prawej stronie przycisku „sortuj”, usuń zaznaczenie opcji „siły różnic” i zaznacz opcję „klucze sortowania”. Następnie zastąp listę elementów w polu tekstowym „Input” następującą listą:
P12B22
P7B18
P12B3
as456456hgjg6786867
P7Bb19
P7BA19
P7BB19
P007B18
P7Bb20
P7Bb19z23
Kliknij przycisk „sortuj”. Pole tekstowe „Wyjście” powinno zawierać następujące elementy:
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 .
Pamiętaj, że klucze sortowania mają strukturę złożoną z wielu pól oddzielonych przecinkami. Każde pole musi być posortowane niezależnie, aby pojawił się kolejny mały problem do rozwiązania, jeśli trzeba zaimplementować to w SQL Server.
P7B12
może zostaćP 07 B 12
(za pośrednictwem ASCII)80 07 65 12
, więc80076512