Как перевести первую букву каждого слова предложения в верхний регистр?
Эта задача возникла как осмысленный пример для демонстрации использования скалярных функций, табличных переменных и новых возможностей языка T-SQL. Итак, требуется создать функцию, которая будет делать первую букву каждого слова заглавной, а остальные - строчными.
Условия:
Условия:
- Слова разделяются единичными пробелами.
- Количество слов произвольно.
Алгоритм:
Итак, функция:
Пояснения.
Функция STRING_AGG, которая использовалась при сборке предложения, имеет обратную функцию STRING_SPLIT (обе эти функции появились в SQL Server 2017), которая как раз выполняет разбивку символьной строки, формируя одностолбцовую таблицу. Использование этой функции напрашивается для решения нашей задачи. Однако, согласно документации, она не гарантирует порядка. В моих примерах строка восстанавливалась правильно, поэтому я приведу и это решение в качестве примера использования функции. Но если вы решите применять её, то делайте это на свой страх и риск.
- Разбиваем фразу на отдельные слова, которые помещаем в табличную переменную.
- Делаем первую букву каждого слова прописной.
- Собираем строку из слов, соблюдая порядок, с помощью функции STRING_AGG.
Итак, функция:
create or alter function firstBigLetter(@name varchar(max))
returns varchar(max)
as
begin
declare @i int = 1, @next int = 1;
declare @t table(id int identity primary key, word varchar(100))
-- Пока подумаем, зачем нам identity?
while @next > 0
begin
select @next=charindex(' ', @name, @i);
if @next=0 -- больше пробелов нет, берем последнее слово
insert into @t(word) select substring(@name, @i, len(@name))
else -- берем очередное слово между @i и @next
insert into @t(word) select substring(@name, @i, @next-@i)
set @i=@next + 1; -- начало следующего слова
end
--Выполняем требуемое преобразование слов
update @t set word= upper(left(word, 1)) + lower(substring(word, 2, len(word)))
-- Сборка и возврат
return(select string_agg(word, ' ')
WITHIN GROUP (ORDER BY id) -- вот зачем нам Identity!
from @t)
end;
go
-- Вызов
select dbo.firstBigLetter('еСли кто-то кое-ГДе у наС порой');
--Результат
Если Кто-то Кое-где У Нас Порой
Пояснения.
- Конструкция CREATE OR ALTER FUNCTION появилась в SQL Server 2017 как аналог CREATE OR REPLACE FUNCTION в PostgreSQL. Теперь не нужно напрягать память, чтобы не забыть поменять ALTER на CREATE после отладки.
- Столбец Identity задает нам порядок, в котором следуют слова в предложении. Поэтому при сборке мы используем сортировку именно по этому столбцу - WITHIN GROUP (ORDER BY id).
- Естественно, можно было не выполнять разбивку на слова, а, например, использовать рекурсивный запрос, но я преследовал тут вполне определенные учебные цели. Если кто-то решит оценить производительность различных алгоритмов, можете поделиться результатами в комментариях.
Функция STRING_AGG, которая использовалась при сборке предложения, имеет обратную функцию STRING_SPLIT (обе эти функции появились в SQL Server 2017), которая как раз выполняет разбивку символьной строки, формируя одностолбцовую таблицу. Использование этой функции напрашивается для решения нашей задачи. Однако, согласно документации, она не гарантирует порядка. В моих примерах строка восстанавливалась правильно, поэтому я приведу и это решение в качестве примера использования функции. Но если вы решите применять её, то делайте это на свой страх и риск.
create or alter function firstBigLetterWithoutOrder(@name varchar(max))
returns varchar(max)
as
begin
return(select string_agg(upper(left(value,1))+lower(substring(value,2,len(value))),' ') from
(select value from STRING_SPLIT(@name,' ')) X)
end
go
--Вызов
select dbo.firstBigLetterWithoutOrder('еСли кто-то кое-ГДе у наС порой');
Обратные ссылки
Автор не разрешил комментировать эту запись
Комментарии
Показывать комментарии Как список | Древовидной структурой