Как в этом случае работает неявное приведение типов в SQL Server? - PullRequest
1 голос
/ 19 ноября 2010

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

SELECT * FROM MyUser WHERE UserId = 123456

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

Msg 245, Level 16, State 1, Line 1
Syntax error converting the nvarchar value 'foo' to a column of data type int.

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

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

Ответы [ 3 ]

3 голосов
/ 19 ноября 2010

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

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

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

2 голосов
/ 19 ноября 2010

Я думаю, это потому, что он не может сравнивать два значения разных типов. Затем 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, но многое можно было бы охватить, поэтому они ограничились наиболее распространенным возможным преобразованием.

1 голос
/ 19 ноября 2010

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

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

...