Не удалось выполнить преобразование, когда значение nvarchar «Торговля» в тип данных int

#sql-server

Вопрос:

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

Не удалось выполнить преобразование, когда значение nvarchar «Торговля» в тип данных int

Но значения являются числами и Trading не найдены в Test2 столбце.

Пожалуйста, помогите…

 SELECT * 
FROM table 
WHERE CoID IN ('', '1') 
  AND ID = 'Test2' 
ORDER BY CAST(Value AS int)
 
CoID(nvarchar) Идентификатор(nvarchar) Значение(nvarchar)
0 Тест1 Торговый
1 Тест2 10
1 Тест2 20
Тест3 азбука

Комментарии:

1. используйте try_convert(int,значение) try_convert() или try_cast() вернет значение NULL, если преобразование завершится неудачно. Гораздо лучше, чем выдавать ошибку.

2. В первой строке Trading в Value столбце — и вы используете ORDER BY CAST(Value AS INT) —-> вот где возникает ошибка преобразования. Если Value столбец имеет тип nvarchar — вы не должны использовать CAST(Value AS INT) его в ORDER BY предложении ….

3. CAST(Value AS int) использует Value столбец и пытается CAST использовать его как int . «Торговля» находится в первой строке ваших выборочных данных для Value столбца. У вас также есть ABC в том же Value столбце, что приведет к той же ошибке. Какая часть этого неясна? Вы не можете CAST использовать значения NVarChar "Trading" или "ABC" to INT .

4. @marc_s, я использовал ID = «test2» в предложении where. «Торговля» означает идентификатор «test1″. Проблема не возникает в моем местном. Это происходит только на сервере. Если я запущу этот запрос на сервере, проблема не возникнет. ВЫБЕРИТЕ * ИЗ (ВЫБЕРИТЕ * ИЗ таблицы, ГДЕ идентификатор В ( » , ‘1’) И ИДЕНТИФИКАТОР = ‘Test2’ ) В ПОРЯДКЕ ПРИВЕДЕНИЯ(значение В таблице РАВНО int)

5. Короткий ответ заключается в том, что кто-то (вы?) попытался сохранить кучу мусора в таблице, где все представляет собой строку. Теперь вы пытаетесь извлечь полезную информацию из этой кучи, но делаете это, делая неверные предположения. Когда все хранится в виде строки и вы сохраняете случайные значения повсюду, вы значительно усложняете написание запросов, логически «избегая» ошибок преобразования. Если вы можете, вернитесь и пересмотрите решения, которые привели к этой схеме. Ваша текущая схема будет постоянным источником ошибок и проблем.

Ответ №1:

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

Вы можете избежать ошибок, используя выражения РЕГИСТРА.

Прочитайте подробный пост о коротком замыкании

 create table TESTShortcircuit (colid nvarchar(30), id nvarchar(30), value nvarchar(30))
insert into TESTShortcircuit
values
('0','Test1',   'Trading'),
('1','Test2',   '10'),
('1','Test2',   '20'),
('','Test3','ABC');

SELECT * 
FROM testShortcircuit 
WHERE ColID IN ('', '1') 
  AND ID = 'Test2' 
ORDER BY (case when try_cast(id as int) is not null then cast(id as int) else null end)
 
колид ID ценность
1 Тест2 10
1 Тест2 20

Комментарии:

1. Эта проблема не возникает в моем локальном, просто происходит на сервере. Связано ли это с исправлением/версией SQL server?

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

3. ISNUMERIC не является хорошей функцией для использования для этой цели. TRY_CONVERT намного лучше.

4. Теперь это довольно запутанное чтение, потому что в нем говорится: «Вы можете избежать ошибок, используя выражения РЕГИСТРА». — а затем показано решение, содержащее нулевые CASE выражения.

5. @Damien_The_Unbeliever, ты прав. извините. обновил свой ответ. выражение case-единственный способ избежать этого короткого замыкания.