Funciones deterministas y no deterministas
Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance
Las funciones deterministas siempre devuelven el mismo resultado cada vez que se llama con un conjunto específico de valores de entrada y tienen el mismo estado de la base de datos. Las funciones no deterministas pueden devolver resultados diferentes cada vez que se les llama con un conjunto específico de valores de entrada, incluso si el estado de la base de datos al que acceden sigue siendo el mismo. Por ejemplo, la función AVG siempre devuelve el mismo resultado dadas las condiciones indicadas anteriormente pero la función GETDATE, que devuelve el valor datetime actual, siempre devuelve un resultado diferente.
Hay varias propiedades de funciones definidas por el usuario que determinan la capacidad del motor de base de datos de SQL Server para indexar los resultados de la función, ya sea a través de índices en columnas calculadas que llaman a la función o a través de vistas indizadas que hacen referencia a la función. El determinismo de una función es una propiedad así. Por ejemplo, no se puede crear un índice agrupado en una vista si esta hace referencia a funciones no deterministas. Para obtener más información sobre las propiedades de las funciones, incluido el determinismo, vea Funciones definidas por el usuario.
Las funciones deterministas deben estar enlazadas al esquema. Use la cláusula SCHEMABINDING
al crear una función determinista.
En este artículo se identifica el determinismo de las funciones del sistema integradas y el efecto en la propiedad determinista de las funciones definidas por el usuario cuando contiene una llamada a procedimientos almacenados extendidos.
Determinar si una función es determinista
Puede comprobar si una función es determinista consultando la propiedad de objeto is_deterministic
de la función. En el ejemplo siguiente se determina si la función Sales.CalculateSalesTax
es determinista.
SELECT OBJECTPROPERTY(OBJECT_ID('Sales.CalculateSalesTax'), 'IsDeterministic');
Determinismo de función integrado
No puede influir en el determinismo de ninguna función integrada. Cada función integrada es determinista o no determinista en función de cómo se implementa la función mediante SQL Server. Por ejemplo, especificar una cláusula ORDER BY en una consulta no cambia el determinismo de una función que se usa en esa consulta.
Todas las funciones integradas de cadena son deterministas, excepto FORMAT. Para obtener una lista de estas funciones, consulte Funciones de cadena (Transact-SQL).
Las siguientes funciones integradas procedentes de categorías de funciones integradas que no son de cadena siempre son deterministas.
- ABS
- ACOS
- ASIN
- ATAN
- ATN2
- CEILING
- COALESCE
- COS
- COT
- DATALENGTH
- DATEADD
- DATEDIFF
- DAY
- DEGREES
- EXP
- FLOOR
- ISNULL
- ISNUMERIC
- LOG
- LOG10
- MONTH
- NULLIF
- POWER
- RADIANS
- ROUND
- SIGN
- SIN
- SQRT
- SQUARE
- TAN
- YEAR
Las siguientes funciones no siempre son deterministas, pero se pueden usar en vistas indizadas o índices en columnas calculadas cuando se especifican de forma determinista.
Función | Comentarios |
---|---|
todas las funciones de agregado | Todas las funciones de agregado son deterministas a menos que se especifiquen con las cláusulas OVER y ORDER BY. Para obtener una lista de estas funciones, consulte Funciones de agregado (Transact-SQL). |
CAST | Deterministas, a menos que se usen con datetime, smalldatetimeo sql_variant. |
CONVERT | Determinista, a menos que se cumpla una de estas condiciones: El tipo de origen es sql_variant. El tipo de destino es sql_variant y su tipo de origen no es determinista. El tipo de origen o destino es datetime o smalldatetime, el otro tipo de origen o destino es una cadena de caracteres, y se especifica un tipo de estilo no determinista. Para que sea determinista, el parámetro de estilo debe ser una constante. Además, los estilos menores o iguales que 100 son no deterministas, salvo los estilos 20 y 21. Los estilos mayores que 100 son deterministas, salvo los estilos 106, 107, 109 y 113. |
CHECKSUM | Determinista, excepto CHECKSUM(*). |
ISDATE | Determinista solo si se utiliza con la función CONVERT, se especifica el parámetro de estilo CONVERT y el estilo no es igual a 0, 100, 9 ni 109. |
RAND | RAND es determinista solo cuando se especifica un parámetro seed . |
Todas las funciones de configuración, cursores, metadatos, seguridad y estadísticas del sistema no son deterministas. Puede ver una lista de estas funciones.
Las siguientes funciones integradas, procedentes de otras categorías, no son deterministas nunca.
- @@CONNECTIONS
- @@CPU_BUSY
- @@DBTS
- @@IDLE
- @@IO_BUSY
- @@MAX_CONNECTIONS
- @@PACKET_ERRORS
- @@PACK_RECEIVED
- @@PACK_SENT
- @@TIMETICKS
- @@TOTAL_ERRORS
- @@TOTAL_READ
- @@TOTAL_WRITE
- AT TIME ZONE
- CUME_DIST
- CURRENT_TIMESTAMP
- DENSE_RANK
- FIRST_VALUE
- FORMAT
- GETDATE
- GETUTCDATE
- GET_TRANSMISSION_STATUS
- LAG
- LAST_VALUE
- LEAD
- MIN_ACTIVE_ROWVERSION
- NEWID
- NEWSEQUENTIALID
- NEXT VALUE FOR
- NTILE
- PARSENAME
- PERCENTILE_CONT
- PERCENTILE_DISC
- PERCENT_RANK
- RAND
- RANK
- ROW_NUMBER
- TEXTPTR
Llamada a procedimientos almacenados extendidos desde funciones
Las funciones que llaman a procedimientos almacenados extendidos no son deterministas porque los procedimientos almacenados extendidos pueden producir efectos secundarios en la base de datos. Los efectos secundarios son cambios de un estado global de la base de datos, como una actualización de una tabla, o de un recurso externo, como un archivo o la red (por ejemplo, la modificación de un archivo o el envío de un mensaje de correo electrónico). No confíe en devolver un conjunto de resultados coherente al ejecutar un procedimiento almacenado extendido desde una función definida por el usuario. No se recomiendan las funciones definidas por el usuario que crean efectos secundarios en la base de datos.
Cuando se llama desde dentro de una función, el procedimiento almacenado extendido no puede devolver conjuntos de resultados al cliente. Las API de Servicios abiertos de datos que devuelven conjuntos de resultados al cliente tienen un código de retorno FAIL.
El procedimiento almacenado extendido puede volver a conectarse a SQL Server. Sin embargo, el procedimiento no puede combinar la misma transacción que la función original que invocó el procedimiento almacenado extendido.
De forma similar a las invocaciones de un procedimiento almacenado o por lotes, el procedimiento almacenado extendido se ejecuta en el contexto de la cuenta de seguridad de Microsoft Windows con la que se ejecuta SQL Server. El propietario del procedimiento almacenado extendido debe tener en cuenta los permisos de este contexto de seguridad al conceder permisos a otros usuarios para ejecutar el procedimiento.