Ошибка преобразования/приведения, NVARCHAR в INT

Я использую SQLServer 2008 R2. У меня есть две таблицы, первая - таблица атрибутов. Второй имеет столбец, который ссылается на таблицу атрибутов. Две таблицы соединены с помощью столбца varchar(32).

#tblA                              #tblB
---------------------              ---------------------
attrib varchar(32)    <--------->  attrib varchar(32)
val nvarchar(255)                  [other fields]
[other fields]

Запрос объединяет таблицы и преобразует #tblA.val в int:

create table #tblA (attrib varchar(32), val nvarchar(255) /*, other fields */)
insert into #tblA values ('vase', 'red'), ('x', '323'), ('y', '615')

create table #tblB (attrib varchar(32) /*, other fields */)
insert into #tblB values ('x'), ('y')

select b.*, cast(a.val as int) as int_val
from   #tblA a inner join #tblB b on a.attrib = b.attrib

drop table #tblB, #tblA

Этот пример работает:

attrib                           int_val
-------------------------------- -----------
x                                323
y                                615

Однако, когда я выполняю тот же запрос к своим производственным таблицам с тысячами записей, я получаю сообщение об ошибке: Ошибка преобразования при преобразовании значения nvarchar 'vase' в тип данных int.

Если я удалю cast() из производственного запроса, я увижу, что возвращенные данные для столбца val содержат только целочисленные значения.

Почему SQL Server пытается преобразовать значения, которые не являются частью возвращаемого набора данных? Еще более странно, если я включу a.val в список выбора в дополнение к cast(a.val as int), ошибок преобразования не будет. Кто-нибудь видел это раньше? Это просто ошибка в SQL Server?

Кстати, использование convert(int, a.val) имеет ту же проблему, что и cast(a.val as int).


person James L.    schedule 18.10.2013    source источник
comment
Вы не должны получить совпадающие строки, используя приведенные выше данные. Если вы измените вставку 2-й таблицы, чтобы вставить в значения #tblB («ваза»), («дно») — ошибка возникает правильно.   -  person NoChance    schedule 19.10.2013
comment
Извините - я подправил пример перед публикацией вопроса. Не заметил, что «верх» и «низ» все еще вставлялись в #tblB. Я хотел использовать «х» и «у».   -  person James L.    schedule 19.10.2013
comment
Не совсем уверен, почему вы получаете это, но могут быть совпадающие строки с нечисловыми данными (например, некоторые данные могут иметь специальные символы, которые не отображаются) или некоторые начальные пробелы или нулевые значения. Другая возможность может заключаться в том, что значение в совпадающей строке превышает пределы int. Я думаю, вы могли бы легко проверить эти 2 случая быстро.   -  person NoChance    schedule 19.10.2013
comment
Уже все проверили. Как это работает сегодня, я делаю select ... into #temp, затем делаю select ..., cast(a.val as int) from #temp, и это работает. Таким образом, значения преобразуются правильно, если я сначала помещаю их в таблицу #temp, а затем выполняю cast(). Так что все данные верные. По какой-то причине SQL Server просто пытается преобразовать невозвращенные строки. Мне кажется, что это ошибка в SQL Server, но я решил опубликовать вопрос здесь, чтобы узнать, кто-нибудь видел это и знает, почему...   -  person James L.    schedule 19.10.2013


Ответы (1)


Я думаю, что это будет иметь отношение к вашей проблеме. Пожалуйста, проверьте принятый ответ. Это не ошибка SQL Server. Это потому, что последовательность операций не является процедурной (что не очень очевидно для большинства).

Порядок приведения в SQL Server Join

Надеюсь это поможет.

person NoChance    schedule 18.10.2013
comment
Это действительно помогло. Это именно то, что я искал. Благодарю вас! - person James L.; 19.10.2013