Как неявное преобразование работает со сравнениями (<>) varchar-представлений целых чисел в SQL Server? - PullRequest
0 голосов
/ 12 октября 2019

У меня есть запрос, где я сравниваю значения с < и >. База данных старая и плохо спроектирована, поэтому, к сожалению, у нас есть столбцы, которые должны быть INT, но вместо этого VARCHAR.

Столбец называется PayCode и имеет тип VARCHAR(50).

Если у меня есть предложение WHERE, подобное следующему:

WHERE PayCode > 200

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

Что я делаюЯ не понимаю, почему нижеприведенное избавляет от этих предупреждений:

WHERE PayCode > '200'

Я понимаю, что я сделал их оба VARCHAR, но логика на самом деле, кажется, работает (это не сравнение по алфавиту)что означало бы, что он конвертирует оба в целые числа в любом случае. Разве это не было бы неявным преобразованием?

Как ни странно, приведенное ниже все еще вызывает предупреждения оценки количества элементов:

WHERE CAST(PayCode AS INT) > 200

Так почему же я могу использовать больше / меньше, чем с VARCHAR представлениямицелые числа и имеют ли логику работу и нет ли неявных проблем преобразования или количества элементов?

Ответы [ 2 ]

2 голосов
/ 12 октября 2019

Так почему же я могу использовать больше / меньше, чем с VARCHAR-представлениями целых чисел, и иметь обе логические функции.

Вы не можете. 3 < 200, но '3' > '200'. При работе с VARCHAR операторы сравнения используют алфавитно-цифровой порядок сортировки, определенный COLLATION.

EG:

drop table if exists #t 

create table #t(PayCode varchar(20))
insert into #t(PayCode) values ('3')

select *
from #t
WHERE PayCode > '200'
1 голос
/ 12 октября 2019

Приоритет типа данных определяет правила:

Когда оператор объединяет выражения разных типов данных, тип данных с более низким приоритетом сначала преобразуется втип данных с более высоким приоритетом. Если преобразование не поддерживается неявным преобразованием, возвращается ошибка. Для оператора, объединяющего выражения операндов, имеющих один и тот же тип данных, результат операции имеет этот тип данных.

В вашем случае есть VARCHAR против INT, поэтому:

WHERE PayCode > 200
-- implicit conversion of PayCode to INT

WHERE PayCode > '200'  (VARCHAR vs VARCHAR)
-- no need for implicit conversion
-- beware that lexicographical order may not always be the same as number order
-- (leading 0, - sign, thousand separator)
...