Перед тем, как я отправлю сообщение о нехватке документации по этому вопросу, подтвердит ли кто-то, что я здесь не что-то упускаю?
На странице документов, где format
указана строковая функция:
«Все встроенные строковые функции являются детерминированными». - Строковые функции (Transact-SQL)
Также нет упоминания о format
недетерминированности на связанных страницах:
Однако при попытке создать постоянный вычисляемый столбец:
create table t (date_col date);
insert into t values (getdate());
alter table t add date_formatted_01 as format(date_col,'YYYY') persisted;
Возвращает следующую ошибку:
Вычисляемый столбец «date_formatted_01» в таблице «t» не может быть сохранен, поскольку столбец недетерминирован.
В документации говорится, что
Если аргумент культуры не указан, используется язык текущего сеанса.
но добавление аргумента культуры ничего не меняет
Это также не удается
alter table t add date_formatted_02 as format(date_col, 'd', 'en-US' ) persisted
демонстрационный ролик: http://rextester.com/ZMS22966
Демоверсия dbfiddle.uk: http://dbfiddle.uk/?rdbms=sqlserver_next&fiddle=7fc57d1916e901cb561b551af144aed6
источник
alter table #t add date_formatted_01 as CONVERT(VARCHAR(20), FORMAT(date_col, 'YYYY', 'en-US')) persisted;
. Не уверен, почемуFORMAT
не является детерминированным, особенно при определении культуры.date_formatted
Колонка может бытьVARCHAR(20)
( по- прежнему сохраняется) и установить с помощью триггера использованияFORMAT
. Или SQLCLR работает. Используя библиотеку SQL # SQLCLR (которую я написал), вы можете сделать этоALTER TABLE SQL#.t ADD date_formatted_03 AS SQL#.Date_Format(date_col, 'd', 'en-US') PERSISTED;
(таблица принадлежит SQL #, поскольку владелец таблицы и функции должен совпадать).Ответы:
Функция не обязательно является детерминированной или недетерминированной. Есть некоторые функции, которые могут быть детерминированными в зависимости от того, как они используются :
CAST
иCONVERT
такие примеры. На основании проведенного вами тестирования, я думаю, что будет справедливо сказать, чтоFORMAT
это не всегда детерминировано, несмотря на то, что это строковая функция. Если вы хотите знать, является ли это порой детерминированным, единственная техника, о которой я могу подумать, - это попробовать достаточно разных способов назвать ее, пока вы не будете удовлетворены. Например, давайте рассмотримFORMAT
применительно к числам. Существует только десять различных типов ввода чисел :Также существует всего девять различных числовых форматов . Можно попытаться создать постоянные столбцы для всех возможных комбинаций. Некоторый код для этого ниже:
Вот пример вывода:
Я не смог получить ни один из столбцов для добавления в таблицу для нескольких входных значений и культур. Я не исчерпывающе попробовал все возможные культуры, потому что не могу найти их список в SQL Server.
Как минимум, можно с уверенностью сделать вывод, что документация, касающаяся детерминизма,
FORMAT
неверна, поэтому я бы порекомендовал представить для нее элемент подключения.источник
FORMAT
Документация теперь обновляется (в ответ на ваш пункт Connect ) , чтобы сказать:Аналогично, String Functions (Transact-SQL) теперь включает в себя:
источник
Я не обычный пользователь sqlserver, поэтому я могу ошибаться, но я предполагаю, что формат не является строковой функцией. Согласно документации:
https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql
Формат принимает в качестве аргумента либо тип даты, либо числовой тип. Если все, что вы хотите сделать, это захватить годичную часть даты, можете ли вы использовать функцию year?
если вы хотите строковое представление:
источник