7.11.25

Новое в SQL Server 2025: изменения в SUBSTRING

Автор: Steve Jones, T-SQL in SQL Server 2025: Substring Changes

Функция SUBSTRING() долгие годы была одним из моих самых употребимых инструментов — то подправить данные, то для вывода части строки. Хотя это очень полезная функция, у неё было одно досадное ограничение, которое в SQL Server 2025 устранено. В этой короткой статье я рассмотрю это изменение.

С выходом новой версии SQL Server мне хотелось осветить некоторые изменения в коде T‑SQL. Это часть серии о том, как язык T‑SQL развивается в этой версии.

Классическая функция SUBSTRING

Многие из вас пользовались SUBSTRING в прошлом, чаще всего чтобы получить частичный взгляд на данные. Например, можно получить список сотрудников и короткий фрагмент заметок о них из базы Northwind. Я выбираю их имя и первые 30 знаков поля с примечаниями.

В приложении мне может понадобиться показать какую‑то часть данных, но не всё, добавив ссылку для получения полного текста при необходимости. Можно поэкспериментировать с объёмом выводимых данных, но и такой подход работает. Можно также сделать и так: допустим, нужно получить только фамилию человека — я нахожу границу между именем и фамилией и вытягиваю оставшуюся подстроку. Например, такой запрос:

SELECT
       CompanyName,
       SUBSTRING(ContactName, CHARINDEX(' ', ContactName), 12) AS ContactLastName,
       ContactName
FROM dbo.Customers;
  

Это даёт компанию и фамилию контактного лица. Здесь потенциально есть недостатки: можно задеть и отчества/вторые имена, но предположим, что в наших данных только имя и фамилия.

Выглядит неплохо, верно? Посмотрим ниже. Если взглянуть на строку 75, видна проблема: фамилия указана как « Braunschwei», тогда как в поле ContactName записано «Art Braunschweiger» (включая имя). Я не учёл длинные фамилии в параметре длины.

Разумеется, это можно исправить, используя LEN() для поля, вот так:

SELECT
       CompanyName,
       SUBSTRING(ContactName, CHARINDEX(' ', ContactName), LEN(ContactName)) AS ContactLastName,
       ContactName
FROM dbo.Customers;
  

Так я делал часто, но об этом нужно помнить. Если не сделать этого и попытаться выполнить запрос без нужной длины, получаю ошибку.

Немного раздражает.

В SQL Server 2025 это исправили

В SQL Server 2025 я могу выполнить тот же запрос, что выше, но уже без ошибки:

Если посмотреть на результаты, строка 75 содержит полную фамилию. Это потому, что функция SUBSTRING берёт длину строки по умолчанию. Мне больше не нужно вычислять её или подставлять произвольное число.

При этом длина возвращаемого фрагмента равна оставшейся части исходной строки. Если добавить в запрос вычисление LEN() от результата, видно, что длины варьируются в зависимости от объёма данных. Вот мой запрос:

SELECT CompanyName,
       SUBSTRING(ContactName, CHARINDEX(' ', ContactName)) AS ContactLastName,
       LEN(SUBSTRING(ContactName, CHARINDEX(' ', ContactName))) AS substringLen,
       LEN(ContactName),
       @@version
FROM dbo.Customers;

Вот результаты с указанием длины:

В этой таблице базы Northwind типы данных — nvarchar. Поиграем с другими типами. Создам новую таблицу и возьму для неё данные из существующей:

CREATE TABLE NewCustomer
(CustomerID INT NOT NULL IDENTITY(1,1) CONSTRAINT NewCustomerPK PRIMARY KEY
, Company VARCHAR(10)
, Contact CHAR(50)
)
GO
INSERT NewCustomer SELECT CustomerID, ContactName FROM dbo.Customers 
GO

Теперь выполню схожий запрос, получая ContactName, подстроку и длины. Результаты для столбца типа CHAR() такие же, как и выше: я получаю не всю «ширину» подстроки (с пробелами), а ровно тот объём данных, который возвращён.

Причина в том, что возвращаемый тип — varchar, а не char. Это указано в документации по SUBSTRING.

Есть одна оговорка: если передать NULL в качестве длины, то есть «забыть» присвоить значение, результатом будет NULL. SQL Server воспринимает это как переданную длину, а не как отсутствующий параметр. Это видно на примере:

Итоги

Вот и всё про это изменение. Начиная с SQL Server 2025, можно опускать параметр длины у SUBSTRING — по умолчанию берётся весь остаток первой строки‑параметра. Возвращаемое значение имеет тип varchar/nvarchar, поэтому конечные пробелы не учитываются.

Это упростит код для многих из нас и приведёт локальную версию SQL Server к единообразию с уже доступными изменениями в Azure.



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

Отправить комментарий