Преобразовать числа подстрок из nvarchar в числовые - PullRequest
0 голосов
/ 03 марта 2020

Я знаю, что здесь много вопросов о преобразовании строк в целые числа в SQL, но я не смог заставить что-либо работать со значением, возвращаемым подстрокой. Я использую функцию подстроки, чтобы вернуть только числа из строки, чтобы я мог сравнить значения, но я получаю ошибку.

Ошибка преобразования типа данных nvarchar в цифры c.

Я попытался запустить следующее:

select 
   sy.ResourceID,
   sy.ResourceType,
   sy.Name0,
   sy.SMS_Unique_Identifier0,
   sy.Resource_Domain_OR_Workgr0,
   sy.Client0,
   Cast(Cast (substring(bio.SMBIOSBIOSVersion0,9,6)as Numeric(4,2)) as Int) as 'BiosVersion'
from v_R_system sy 
   inner join v_GS_FIRMWARE firm on firm.ResourceID = sy.ResourceId 
   inner join v_GS_COMPUTER_SYSTEM CS on cs.ResourceID = sy.ResourceId 
   inner join v_GS_PC_BIOS Bio on bio.ResourceID = sy.ResourceId 
where firm.SecureBoot0 != 1 and cs.Model0 = 'HP EliteBook 840 G3'

Приведение к типу int округляет до 1, когда оно должно быть 01.43 в зависимости от того, что получает подстрока. Когда я удаляю приведение как int и просто преобразую в число c, оно усекает его 1.42. Когда я пытаюсь сравнить его со значением, которое я указываю, я все равно получаю ошибку, указанную выше.

select 
   sy.ResourceID,
   sy.ResourceType,
   sy.Name0,
   sy.SMS_Unique_Identifier0,
   sy.Resource_Domain_OR_Workgr0,
   sy.Client0,
   Cast(substring(bio.SMBIOSBIOSVersion0,9,6)as Numeric(4,2)) as 'BiosVersion'
from v_R_system sy 
   inner join v_GS_FIRMWARE firm on firm.ResourceID = sy.ResourceId 
   inner join v_GS_COMPUTER_SYSTEM CS on cs.ResourceID = sy.ResourceId 
   inner join v_GS_PC_BIOS Bio on bio.ResourceID = sy.ResourceId 
where firm.SecureBoot0 != 1 and cs.Model0 = 'HP EliteBook 840 G3' 
   and Cast(substring(bio.SMBIOSBIOSVersion0,9,6)as Numeric(4,2)) < 01.42

Это проблема с моим сравнением или проблема с форматированием?

Продукт:

  • Microsoft SQL Серверный стандарт (64-разрядный)
  • Версия: 2016 (v13.0.4604.0)
  • Язык: английский sh (США)
  • Сортировка: SQL_Latin1_General_CP1_CI_AS

Ответы [ 4 ]

1 голос
/ 03 марта 2020

Скорее всего, вы получаете ведущий пробел через ваш substring. Попробуйте начать с 10 вместо 9. И используйте предложение where, чтобы ограничить набор результатов только квалификационными записями

cast(substring(bio.SMBIOSBIOSVersion0,10,6) as numeric(4,2))
1 голос
/ 03 марта 2020

Простое исправление - try_cast() вместо cast():

try_Cast(try_Cast(substring(bio.SMBIOSBIOSVersion0, 9, 6)as Numeric(4,2)) as Int) as BiosVersion
0 голосов
/ 03 марта 2020

Приведение к типу int округляет до 1, когда оно должно быть 01.43 в зависимости от того, что получает подстрока. Когда я удаляю приведение как int и просто конвертирую как число c, оно усекает его 1.42.

Сначала проблема округления. Если у вас больше точности, чем две цифры, вам нужно привести тип к цифре c, который включает в себя все возможных цифр, поскольку любая из этих цифр может оказаться в ie -брейкере для какой способ округлить. После того, как вы выполните это приведение, используйте функцию ROUND(), чтобы получить точность, которая вам действительно нужна.

Вы также, похоже, заботитесь о ведущем 0, по крайней мере, в предложении SELECT. Я советую против этого. Пусть клиентский код беспокоится о точном форматировании чисел и дат. Но если вам это действительно нужно, вам нужна функция FORMAT(). Опять же, используйте это после приведения к цифре c, но вы можете использовать его для замены ROUND(). При импорте это снова создает строковое значение, а не числовое значение c, поэтому используйте его только для предложения SELECT, когда клиентская программа или отчет ожидает строковые данные.

Наконец, есть ситуация в предложении WHERE с некоторыми неверными приведениями. Проблема здесь в том, что вы не можете заставить SQL Server выполнить условия в предложении WHERE в любом указанном порядке c. Sql Сервер будет обрабатывать эти фильтры в том порядке, который он считает наиболее эффективным, даже если некоторые из них нужны скорее по логическим причинам.

Имея это в виду, вам следует обратить внимание на использование TRY_CAST() в предложении WHERE. Это позволит вам безопасно привести эти подстроки к значениям цифр c, даже до того, как другие необходимые фильтры будут завершены.

0 голосов
/ 03 марта 2020

В качестве альтернативы приведению вы можете принудительно указать 'цифру c контекст', добавив 0.

select ...
0+substring(bio.SMBIOSBIOSVersion0,9,6) as 'BiosVersion'

Это может зависеть от вашего вида базы данных и ее версии. Пожалуйста, укажите.

Возможно, у вас есть данные, в которых указанная подстрока не является цифрой c. В этом случае try_cast будет работать (см. Другой ответ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...