Детерминированное преобразование INT в T-SQL

Данный:

  • SQL-сервер
  • Стол под названием TEST_TABLE
  • Столбец в TEST_TABLE с именем TEST_FIELD типа VARCHAR(50) NOT NULL
  • 1-й ряд: 10 изн. 3/6 изн.
  • Ряд 2: 10Y3/2 ст.
  • Запрос: SELECT TEST_FIELD FROM TEST_TABLE WHERE ...

Вопрос:

В моем условии, где мне нужно проверить значения в последнем символе строки. Я замечаю такое же поведение, делая следующее в предложении Where.

  1. RIGHT(TEST_FIELD,1) > 3
  2. CAST(RIGHT(TEST_FIELD,1) AS INT) > 3

Ведут ли они себя одинаково через некоторый предполагаемый состав в случае 1? Является ли случай 1 детерминированным?

Заранее спасибо.

Мэтт


person Mathew A.    schedule 22.12.2011    source источник


Ответы (2)


Преобразование выполняется, когда вы проверяете значение, например:

DECLARE @t varchar(100)

SET @t = (SELECT 'ABCA2')

SELECT @t    

IF RIGHT(@t, 2) > 10
  SELECT 'Hi'
ELSE
  SELECT 'Bye'

Выдаст ошибку, потому что SQL не может преобразовать A2 в целое число без ошибки.

Однако, если вы замените @t на:

SET @t = (SELECT 'ABC12')

Приведенный выше код будет работать, если преобразование прошло успешно и можно будет провести сравнение. Сама правильная функция не преобразует ваше значение. MSDN явно указывает возвращаемый тип RIGHT():

Возвращает varchar, если character_expression является символьным типом данных, отличным от Unicode.

Возвращает nvarchar, если character_expression является символьным типом данных Unicode.

Чтобы облегчить себе задачу, исключите функцию RIGHT() вообще, когда сравнение выполняется, например, с текстом:

DECLARE @t varchar(100)

SET @t = (SELECT '1')

SELECT @t

IF @t < 10
  SELECT 'Hi'
ELSE
  SELECT 'Bye'

Заметьте, я не звонил Right(). Результатом вышеизложенного является отображение 1, а затем текста Hi.

person JonH    schedule 22.12.2011
comment
Итак, в моем случае у меня есть несколько уникальных значений в самом значении. 10YR3/6. 10, 3 и 6. Если не использовать правильно, то получится пюре, не так ли? 1036? или хуже 10 вместо 3 или 6? Не уверен в этом поведении, поэтому мой вопрос продолжается с учетом этого. - person Mathew A.; 22.12.2011
comment
@MattAkers - Если вы можете проанализировать значения, чтобы получить 10, 3 и 6 соответственно, тогда все в порядке. Если вы не можете, то сравнение вашего текста с целочисленным типом данных вызовет исключение. Вы не можете сравнить 10YR3/6 со значением, скажем, 100. Он не знает, как выполнить операцию, и это не имеет ничего общего с Right() или даже Left(), это больше связано с преобразованием при сравнении готово. Имеет ли это смысл? - person JonH; 22.12.2011
comment
Это имеет смысл. Полностью согласен с вашими примерами и комментариями. Более того, мой вопрос о том, когда и где преобразование сравнения пройдет / не пройдет, заключается в следующем: почему пункты 1 и 2 работают одинаково, и если 1, похоже, выполняет приведение в черном ящике, действительно ли мне нужно приводить его напрямую? И имеет ли пункт 1 where детерминированное поведение? - person Mathew A.; 22.12.2011
comment
and if 1 appears to be having a cast done in the black box, do I really need to cast it outright? Нет, вам не нужно его разыгрывать. And does where clause 1 have deterministic behavior? Да - person Ben English; 22.12.2011

И да, случай 1 является детерминированным - либо успешное неявное преобразование из строки в целое число (конец, затем сравнение между двумя целыми числами), либо выдается исключение.

person bako_mite    schedule 22.12.2011
comment
Спасибо Бако. Это то, что я искал. Ваше здоровье! - person Mathew A.; 22.12.2011