#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"
toINT
.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-единственный способ избежать этого короткого замыкания.