Используйте SQLCLR UDT. Это может сработать, хотя неясно, представляет ли это чистый выигрыш по сравнению с подходом, описанным выше.
Да, в SQLCLR UDT операторы сравнения могут быть переопределены пользовательскими алгоритмами. Это обрабатывает ситуации, когда значение сравнивается либо с другим значением того же пользовательского типа, либо с тем, которое необходимо неявно преобразовать. Это должно обрабатывать фильтр диапазона в WHERE
условии.
Что касается сортировки UDT как обычного типа столбца (не вычисляемого столбца), это возможно только в том случае, если UDT имеет «байтовый порядок». Быть «упорядоченным в байтах» означает, что двоичное представление UDT (которое может быть определено в UDT) естественно сортируется в соответствующем порядке. Предполагая, что двоичное представление обрабатывается аналогично подходу, описанному выше для столбца VARCHAR (50), который имеет сегменты фиксированной длины, которые дополняются, это будет соответствовать. Или, если было непросто убедиться, что двоичное представление естественным образом упорядочено надлежащим образом, вы можете предоставить метод или свойство UDT, которые выводят значение, которое будет правильно упорядочено, и затем создать PERSISTED
вычисляемый столбец для этого. метод или свойство. Метод должен быть детерминированным и помечен как IsDeterministic = true
.
Преимущества этого подхода:
- Нет необходимости в поле «оригинальное значение».
- Не нужно вызывать UDF для вставки данных или сравнения значений. Предполагая, что
Parse
метод UDT принимает P7B18
значение и преобразует его, вы можете просто вставить значения естественным образом как P7B18
. А с помощью метода неявного преобразования, установленного в UDT, условие WHERE также позволяет использовать просто P7B18`.
Последствия такого подхода:
- Простой выбор поля вернет двоичное представление, если в качестве типа данных столбца используется UDT, упорядоченный в байтах. Или, если использовать
PERSISTED
вычисляемый столбец для свойства или метода UDT, вы получите представление, возвращаемое свойством или методом. Если вам нужно исходное P7B18
значение, то вам нужно вызвать метод или свойство UDT, которое закодировано, чтобы вернуть это представление. Так как вы ToString
все равно должны переопределить метод, это хороший вариант для этого.
Неясно (по крайней мере для меня сейчас, поскольку я не тестировал эту часть), насколько легко / сложно было бы внести какие-либо изменения в двоичное представление. Изменение сохраненного сортируемого представления может потребовать удаления и повторного добавления поля. Кроме того, удаление сборки, содержащей UDT, не удастся, если используется каким-либо образом, поэтому вы должны убедиться, что в сборке не было ничего кроме этого UDT. Вы можете ALTER ASSEMBLY
заменить определение, но на это есть некоторые ограничения.
С другой стороны, VARCHAR()
поле - это данные, которые отсоединены от алгоритма, поэтому потребуется только обновить столбец. И если есть десятки миллионов строк (или больше), то это можно сделать в пакетном режиме.
Реализовать ICU библиотека , которая фактически позволяет для делать это буквенно - цифровой сортировки. Несмотря на высокую функциональность, библиотека поставляется только на двух языках: C / C ++ и Java. Это означает, что вам может потребоваться внести некоторые изменения, чтобы заставить его работать в Visual C ++, или есть вероятность, что код Java может быть преобразован в MSIL с использованием IKVM . На этом сайте есть один или два проекта стороны .NET, которые предоставляют интерфейс COM, к которому можно получить доступ в управляемом коде, но я считаю, что они не обновлялись в течение некоторого времени, и я не пробовал их. Лучше всего было бы обрабатывать это на уровне приложения с целью генерации ключей сортировки. Ключи сортировки будут сохранены в новом столбце сортировки.
Это может быть не самый практичный подход. Тем не менее, все еще очень круто, что такая способность существует. Я предоставил более подробный обзор этого примера в следующем ответе:
Существует ли сортировка для сортировки следующих строк в следующем порядке 1,2,3,6,10,10A, 10B, 11?
Но шаблон, который рассматривается в этом вопросе, немного проще. Для примера, показывающего, что тип шаблона, рассматриваемый в этом Вопросе, также работает, перейдите на следующую страницу:
ICU Collation Demo
В разделе «Настройки» установите «числовой» параметр на «вкл.», А для всех остальных - «по умолчанию». Далее, справа от кнопки «Сортировка», снимите флажок с «Сила различий» и установите флажок «Ключи сортировки». Затем замените список элементов в текстовой области «Ввод» следующим списком:
P12B22
P7B18
P12B3
as456456hgjg6786867
P7Bb19
P7BA19
P7BB19
P007B18
P7Bb20
P7Bb19z23
Нажмите кнопку «Сортировка». В текстовой области «Вывод» должно отображаться следующее:
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 .
Обратите внимание, что ключи сортировки имеют структуру в нескольких полях, разделенных запятыми. Каждое поле должно быть отсортировано независимо, поэтому возникает еще одна небольшая проблема, которую необходимо решить, если необходимо реализовать это в SQL Server.
P7B12
могло бы статьP 07 B 12
, то (через ASCII)80 07 65 12
, так80076512