Как я могу выводить текст до тех пор, пока он не станет ascii в SQL?

#sql #tsql #while-loop #char #ascii

Вопрос:

Как я могу выводить текст до тех пор, пока он не станет ascii в SQL?

Вот что я пытаюсь сделать:

 DECLARE @input VARCHAR(20)
SET @input = 'text'

DECLARE @index INT
SET @index = 1

DECLARE @output VARCHAR(32)
SET @output = ''

WHILE CHAR(ASCII(SUBSTRING(@input, @index, 1))) LIKE '[ -~]'
BEGIN
    SET @output = @output   CHAR(ASCII(SUBSTRING(@input, @index, 1)))
    SET @index = @index   1
END

SELECT @output
 

Но в конце концов я получаю пустую строку. Почему? Что я здесь упускаю?

Я ожидаю, что значение @output будет 'text' в конце сценария.

Обновить

Если я обновлю сценарий до

 DECLARE @input VARCHAR(20)
SET @input = 'text'

DECLARE @index INT
SET @index = 1

DECLARE @output VARCHAR(32)
SET @output = ''

WHILE CHAR(ASCII(SUBSTRING(@input, @index, 1))) LIKE '[a-b]'
BEGIN
    SET @output = @output   CHAR(ASCII(SUBSTRING(@input, @index, 1)))
    SET @index = @index   1
END

SELECT @output
 

Это будет работать так, как ожидалось. Но здесь я просто сократил набор со всех печатаемых символов ascii до только маленьких букв. Почему сокращенный набор [a-b] включает text символы, а расширенный набор [ -~] -нет?

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

1. NOT LIKE ? Или что LIKE должен делать этот предикат? Но вы могли бы сделать это как один лайнер SELECT ISNULL(SUBSTRING(@input, 1, NULLIF(PATINDEX('%[ -~]%', @input), 0)), @input)

2. @Charlieface, но что не так в моей реализации? LIKE Проверяет, что a char является ASCII.

3. Понятия не имею, поскольку я не знаю, что вы пытаетесь сделать, что означает «Пока это не ASCII», запрос в его нынешнем виде пытается найти пробел, тире или тильду, все из которых являются символами ASCII

4. @Charlieface, запрос повторяет входные символы один за другим и добавляет символы к выходным, пока не встретит первый символ, отличный от ascii.

5. Итак, как я и думал: вы пытаетесь вывести до первого символа, отличного от ASCII (и я не знаю, что это значит), но это не то, что делает этот запрос, он возвращает все символы, соответствующие пробелу, тире, тильде

Ответ №1:

Пробел не является допустимым разделителем диапазона, поэтому LIKE [ -~] он не будет работать. Это становится тестом только для этих трех персонажей.

Вы можете проверить код ASCII напрямую, а не с помощью LIKE :

 DECLARE @input VARCHAR(20)
SET @input = 'text'

DECLARE @index INT
SET @index = 1

DECLARE @output VARCHAR(32)
SET @output = ''

WHILE ASCII(SUBSTRING(@input, @index, 1)) BETWEEN 32 AND 126
BEGIN
    SET @output = @output   CHAR(ASCII(SUBSTRING(@input, @index, 1)))
    SET @index = @index   1
END

SELECT @output
 

ДЕМОНСТРАЦИЯ

Примечание: С диапазонами можно получить неожиданные результаты LIKE , поскольку сравнение зависит от параметров сортировки.


Ответ скопирован из дубликата вопроса об администраторах баз данных