Поделиться через


Детерминированные и недетерминированные функции

Детерминированные функции каждый раз возвращают один и тот же результат, если предоставлять им один и тот же набор входных значений и использовать одно и то же состояние базы данных. Недетерминированные функции могут возвращать каждый раз разные результаты, даже если предоставлять им один и тот же набор входных значений и использовать одно и то же состояние базы данных. Например, функция AVG всегда возвращает один результат при указанных выше условиях, а функция GETDATE, возвращающая текущие дату и время, всегда возвращает разный результат.

Существует несколько свойств определяемых пользователем функций, которые определяют способность SQL Server компонент Database Engine индексировать результаты функции либо с помощью индексов вычисляемых столбцов, вызывающих функцию, либо с помощью индексированных представлений, ссылающихся на функцию. Детерминизм функции — одно из таких свойств. Например, в представлении нельзя создать кластеризованный индекс, если оно ссылается на какие-либо недетерминированные функции. Дополнительные сведения о свойствах функций, включая детерминизм, см. в разделе Определяемые пользователем функции.

В этом разделе описан детерминизм встроенных системных функций и их влияние на свойство детерминированности определяемых пользователем функций, если оно содержит вызов расширенных хранимых процедур.

Детерминизм встроенных функций

На детерминизм встроенных функций повлиять нельзя. Каждая встроенная функция детерминирована или недетерминирована в зависимости от того, как функция реализуется SQL Server. Например, указав в запросе предложение ORDER BY, детерминизм функции, используемой в этом запросе, не изменится.

Все встроенные строковые функции являются детерминированными. Список этих функций см. в разделе Строковые функции (Transact-SQL).

Следующие встроенные функции, отличные от строковых функций, всегда детерминированы.

ABS DATEDIFF POWER
ACOS DAY RADIANS
ASIN DEGREES ROUND
ATAN EXP SIGN
ATN2 FLOOR SIN
CEILING ISNULL SQUARE
COALESCE ISNUMERIC SQRT
COS LOG TAN
COT LOG10 YEAR
DATALENGTH MONTH
DATEADD NULLIF

Следующие функции не всегда детерминированы, их можно использовать в индексированных представлениях или индексах вычисляемых столбцов, если они заданы детерминированным образом.

Компонент Комментарии
все агрегатные функции Все агрегатные функции являются детерминированными, если они не указаны с помощью предложения OVER или ORDER BY. Список этих функций см. в разделе Агрегатные функции (Transact-SQL).
CAST Детерминирована, кроме случаев использования с datetime, smalldatetime или sql_variant.
CONVERT Детерминирована, кроме следующих случаев.

Исходный тип — sql_variant.

Конечный тип — sql_variant, и его исходный тип недетерминирован.

Исходный или конечный тип — datetime или smalldatetime, другой исходный или конечный тип — строка символов, и задан недетерминированный стиль. Чтобы быть детерминированным, параметр стиля должен быть константой. Кроме того, стили, которые меньше или равны 100, являются недетерминированными, за исключением стилей 20 и 21. Стили более 100 являются детерминированными, за исключением стилей 106, 107, 109 и 113.
CHECKSUM Детерминирована, за исключением CHECKSUM(*).
ISDATE Детерминирована, только если используется с функцией CONVERT, при этом параметр стиля CONVERT задан, но не равен 0, 100, 9 или 109.
RAND Функция RAND детерминирована, только если параметр seed определен.

Все функции конфигурации, курсора, метаданных, безопасности и системные статистические — недетерминированные. Список этих функций см. в разделах Функции конфигурации (Transact-SQL),Функции курсора (Transact-SQL),Функции метаданных (Transact-SQL),Функции безопасности (Transact-SQL) и Системные статистические функции (Transact-SQL).

Следующие встроенные функции других классов всегда недетерминированы.

@@CONNECTIONS GETDATE
@@CPU_BUSY GETUTCDATE
@@DBTS GET_TRANSMISSION_STATUS
@@IDLE LAG
@@IO_BUSY LAST_VALUE
@@MAX_CONNECTIONS LEAD
@@PACK_RECEIVED MIN_ACTIVE_ROWVERSION
@@PACK_SENT NEWID
@@PACKET_ERRORS NEWSEQUENTIALID
@@TIMETICKS NEXT VALUE FOR
@@TOTAL_ERRORS NTILE
@@TOTAL_READ PARSENAME
@@TOTAL_WRITE PERCENTILE_CONT
CUME_DIST PERCENTILE_DISC
CURRENT_TIMESTAMP PERCENT_RANK
DENSE_RANK RAND
FIRST_VALUE RANK
ROW_NUMBER
TEXTPTR

Вызов расширенной хранимой процедуры из функций

Функции, вызывающие расширенные хранимые процедуры, недетерминированы, так как расширенные хранимые процедуры могут оказать на базу данных побочное действие. Побочные действия — это такое изменение глобального состояния базы данных, как обновление таблицы, внешнего сетевого ресурса или файла. Например, к таким действиям можно отнести изменение файла или отправку сообщения по электронной почте. При вызове расширенной хранимой процедуры из пользовательской функции не следует полагаться на то, что будет возвращен непротиворечивый результирующий набор. Не рекомендуется применять пользовательские функции, которые оказывают побочное действие на базу данных.

При вызове из функции расширенные хранимые процедуры не могут вернуть клиенту результирующий набор. API-интерфейс любых открытых служб данных, который возвращает результирующие наборы клиенту, будет иметь код возврата FAIL.

Расширенная хранимая процедура может подключаться обратно к SQL Server. Однако процедура не может соединиться с той же транзакцией, что и первоначальная функция, которая вызвала расширенную хранимую процедуру.

Как и вызовы из пакета или хранимой процедуры, расширенная хранимая процедура выполняется в контексте учетной записи безопасности Microsoft Windows, под которой выполняется SQL Server. Владелец расширенной хранимой процедуры должен иметь это в виду при предоставлении разрешения на выполнение этой процедуры другим пользователям.