Как в этом случае работает неявное приведение типов в SQL Server?

Когда я пытаюсь этот специальный запрос в SQL Server (предположим, UserId поле NVARCHAR):

SELECT * FROM MyUser WHERE UserId = 123456

Я получаю эту ошибку:

Сообщение 245, Уровень 16, Состояние 1, Строка 1
Синтаксическая ошибка при преобразовании значения nvarchar 'foo' в столбец типа данных int.

Очевидно, что есть значение 'foo' где-то внизу UserId колонка.

Почему SQL Server пытается преобразовать весь мой столбец в INTEGER, а не делает то, что мне кажется очевидным: преобразование значения моего поиска в NVARCHAR?

3 ответа

Решение

Сравнение выполняется с использованием правил Приоритета типов данных:

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

NVARCHAR тип (приоритет 25) преобразуется в int (приоритет 16). Обратите внимание, что приоритет 1 означает "самый высокий".

Я думаю, что это потому, что он не может сравнивать два значения разных типов. Затем is должен преобразовать оба элемента сравнения равенства в один и тот же тип. Вот, int предпочтительнее, я думаю.

Я верю int имеет приоритет над nvarchar тип, поэтому он должен неявно пытаться преобразовать nvarchar к значению int.

РЕДАКТИРОВАТЬ # 1

"Но не будет ли разумно попытаться преобразовать значение, которое я дал, в тип поля, в котором я ищу, а не наоборот?"

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

where dateOfBirth = 1976-6-16

против

where dateOfBirth = N'1976-06-16'

В первом примере, каково намерение пользователя? Это проверить dateOfBirth равно значению даты 1976-06-16 или сравнить с целочисленным значением 1976 - 6 - 16, что приведет к 1954что может быть достаточно разумным, чтобы считать его годом любой данной даты.

Я думаю, что есть неявные преобразования, такие nvarchar в datetime, но было бы много, чтобы покрыть, поэтому они ограничились наиболее распространенным возможным преобразованием.

Почему вы указываете целочисленное значение, если знаете, что столбец - это NVARCHAR?

К сожалению, SQL Server, как и многие другие реализации SQL, сильно отстает от других языков в поддержке типов. Проверка типа обычно выполняется только во время выполнения. Таким образом, такие запросы, как ваш, не проверяются синтаксисом, чтобы выделить проблемы, подобные той, которая у вас есть. Ваш запрос ошибочен, потому что вы не соответствуете различным типам, но поскольку SQL Server не проверяет его, результаты будут непредсказуемыми, в зависимости от данных.

Другие вопросы по тегам