Детерминированные и недетерминированные функции
Детерминированные функции каждый раз возвращают один и тот же результат, если предоставлять им один и тот же набор входных значений и использовать одно и то же состояние базы данных. Недетерминированные функции могут возвращать каждый раз разные результаты, даже если предоставлять им один и тот же набор входных значений и использовать одно и то же состояние базы данных.
Определяемые пользователями функции имеют несколько свойств, определяющих способность ядра SQL Server Database Engine индексировать результаты функции как с помощью индексов вычисляемых столбцов, вызывающих функцию, так и с помощью индексированных представлений, которые на нее ссылаются. Детерминизм функции — одно из таких свойств. Например, в представлении нельзя создать кластеризованный индекс, если оно ссылается на какие-либо недетерминированные функции. Дополнительные сведения о свойствах функций, включая детерминизм, см. в разделе Правила написания определяемых пользователем функций.
В этом разделе описан детерминизм встроенных системных функций и их влияние на свойство детерминированности определяемых пользователем функций, если оно содержит вызов расширенных хранимых процедур.
Детерминизм встроенных функций
На детерминизм встроенных функций повлиять нельзя. Каждая из них детерминирована или недетерминирована в зависимости от реализации в SQL Server.
Все статистические и строковые встроенные функции детерминированы. Список этих функций см. в разделе Статистические функции (Transact-SQL) и Строковые функции (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 |
|
Следующие функции не всегда детерминированы, их можно использовать в индексированных представлениях или индексах вычисляемых столбцов, если они заданы детерминированным образом.
Функция |
Комментарии |
---|---|
CAST |
Детерминирована, кроме случаев использования с datetime, smalldatetime или sql_variant. |
CONVERT |
Детерминирована, кроме следующих случаев.
|
CHECKSUM |
Детерминирована, за исключением CHECKSUM(*). |
ISDATE |
Детерминирована, только если используется с функцией CONVERT, при этом аргумент стиля CONVERT задан, но не равен 0, 100, 9 или 109. |
RAND |
Функция RAND детерминирована, только если аргумент seed определен. |
Все функции конфигурации, курсора, метаданных, безопасности и системные статистические — недетерминированные. Список этих функций см. в разделах Функции конфигурации (Transact-SQL), Функции работы с курсорами (Transact-SQL), Функции метаданных (Transact-SQL), Функции безопасности (Transact-SQL) и Системные статистические функции (Transact-SQL).
Следующие встроенные функции других классов всегда недетерминированы.
@@CONNECTIONS |
@@TOTAL_WRITE |
@@CPU_BUSY |
CURRENT_TIMESTAMP |
@@DBTS |
GETDATE |
@@IDLE |
GETUTCDATE |
@@IO_BUSY |
GET_TRANSMISSION_STATUS |
@@MAX_CONNECTIONS |
MIN_ACTIVE_ROWVERSION |
@@PACK_RECEIVED |
NEWID |
@@PACK_SENT |
NEWSEQUENTIALID |
@@PACKET_ERRORS |
PARSENAME |
@@TIMETICKS |
RAND |
@@TOTAL_ERRORS |
TEXTPTR |
@@TOTAL_READ |
Вызов расширенной хранимой процедуры из функций
Функции, вызывающие расширенные хранимые процедуры, недетерминированы, так как расширенные хранимые процедуры могут оказать на базу данных побочное действие. Побочные действия — это такое изменение глобального состояния базы данных, как обновление таблицы, внешнего сетевого ресурса или файла. Например, к таким действиям можно отнести изменение файла или отправку сообщения по электронной почте. При вызове расширенной хранимой процедуры из пользовательской функции не следует полагаться на то, что будет возвращен непротиворечивый результирующий набор. Не рекомендуется применять пользовательские функции, которые оказывают побочное действие на базу данных.
При вызове из функции расширенные хранимые процедуры не могут вернуть клиенту результирующий набор. API-интерфейс любых открытых служб данных, который возвращает результирующие наборы клиенту, будет иметь код возврата FAIL.
Расширенная хранимая процедура может подключиться обратно к SQL Server. Однако процедура не может присоединиться к той же транзакции, что и первоначальная функция, которая вызвала расширенную хранимую процедуру.
Аналогично вызовам из пакетной или хранимой процедуры расширенная хранимая процедура выполняется в контексте той учетной записи защиты Microsoft Windows, под которой запущен SQL Server. Владелец расширенной хранимой процедуры должен иметь это в виду при предоставлении разрешения на выполнение этой процедуры другим пользователям.
См. также