Детерминированные и недетерминированные функции
Детерминированные функции каждый раз возвращают один и тот же результат, если предоставлять им один и тот же набор входных значений и использовать одно и то же состояние базы данных. Недетерминированные функции могут возвращать каждый раз разные результаты, даже если предоставлять им один и тот же набор входных значений и использовать одно и то же состояние базы данных. Например, функция 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. Владелец расширенной хранимой процедуры должен иметь это в виду при предоставлении разрешения на выполнение этой процедуры другим пользователям.