Сопоставление поля с переменным числом ведущих нулей в таблице SQL Server - PullRequest
4 голосов
/ 05 февраля 2010

У меня есть ситуация, когда у меня есть значение входящих данных, которые могут иметь или не иметь начальные нули. Мне нужно сопоставить это с полем / строкой в ​​таблице SQL Server. Значение поля в базе данных SQL Server может также иметь или не иметь начальные нули.

Итак, я мог бы иметь:

  • входящий = 5042800138
    и значение в дБ может быть любым из 5042800138, 05042800138, 005042800138, 0005042800138

  • или входящий может быть 005042800138
    и значение в дБ может быть любым из 5042800138, 05042800138, 005042800138, 0005042800138

Решение, которое я придумал, состояло в том, чтобы убрать начальные нули (всегда) во входящих данных и использовать SQL, как в следующем примере:

-- this simulates the incoming value to check
-- i strip out the leading zeroes.
declare @tryUPC as varchar(40)
set @tryUPC = '5042800138'

-- try to find it in the database and ignore leading zeroes
select prod_uid, prod_partno, prod_upc
from products as p
where (prod_upc = @tryUPC) or 
   (
   len(prod_upc) > len(@tryUPC)
   and right(prod_upc, len(@tryUPC)) = @tryUPC
   and stuff(prod_upc, 1, len(prod_upc) - len(@tryUPC), '0') = prod_upc
   )

Кажется, это работает. У меня вопрос, я что-то упустил? Есть ли у SQL Server лучший способ справиться с этим? Я использую SQL Server 2005.

tia,

дон

Ответы [ 3 ]

4 голосов
/ 05 февраля 2010

Просто еще один уклон (исправление данных было бы лучше, но принятый ответ - также достойный обходной путь): добавьте постоянный, индексированный вычисляемый столбец «actualUPC», который является символьным типом, вычисляемым с правильным числом ведущих нулей. Пример:

Если предполагается, что «реальный» код состоит из 12 цифр, создайте вычисляемый столбец, например

 right( '000000000000' + originalColumn, 12 )

Таким образом, входные данные действительно корректируются, затем корректно индексируются и могут быть найдены с помощью индекса.

Когда вы запрашиваете, также дополняйте вводимые данные как константу в запросе.

Проверьте ограничения на индексированные вычисляемые столбцы, прежде чем сходить с ума.

Кстати, коды BTW (почтовые индексы, серийные номера, номера ssn и т. Д.) Должны ВСЕГДА храниться в виде текстовых данных с ведущими нулями и НИКОГДА не в виде целого или числового типа. Возьми его у парня, который вырос в почтовом индексе 01033.

2 голосов
/ 05 февраля 2010

Если вы не можете изменить существующие данные, чтобы убрать лидирующие нули / преобразовать в INT, может быть быстрее сделать что-то вроде этого:

WHERE prod_upc IN (@tryUPC, '0' + @tryUPC, '00' + @tryUPC, '000' + @tryUPC [...])

Это примерно так же элегантно, как моя нога, но оно будет более статичным и разборчивым и (вероятно) с большей вероятностью достигнет любого соответствующего индекса.

Предполагается, что существует ограниченное количество ведущих нулей, заметьте. Преобразование данных в INT (или добавление нового столбца INT и вычисление его при вставке), вероятно, будет лучшим решением проблемы.

0 голосов
/ 05 февраля 2010

1) обновить все существующие данные, чтобы не иметь начальных нулей, возможно использовать тип данных BIGINT
2) всегда удаляйте начальные нули из входных данных перед сохранением и поиском
3) никогда больше не беспокойтесь о ведущих нулях, и вы действительно можете использовать индекс!

EDIT после комментария ОП:

было бы неплохо, но это не реальность. Я полагаю, я должен был упомянуть, что это устаревшее приложение. коды upc могут быть введены в кучу разных мест. изменение типа данных потребует массового рефракторинга. кроме того, иногда нужны нули - есть веская причина для базы данных быть такой, какая она есть. - Дон Дикинсон

Вы можете использовать постоянный вычисляемый столбец, в котором вы REVERSE () столбец, а затем индексировать его. Затем вы можете запросить:

WHERE Column1Reverse Like REVERSE('1234567')+'%' --can use the persistent computed column's index

Чтобы добавить сохраненный вычисляемый столбец (который переворачивает строку) и индексировать по нему, используйте этот код:

ALTER TABLE YourTable ДОБАВИТЬ ReversedYourString КАК ОБРАТНАЯ (YourString) СОХРАНЕННАЯ

CREATE NONCLUSTERED INDEX IX_YourTable_ReversedYourString 
ON YourTable (ReversedYourString) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...