Hola, chicos,
¡Buenas tardes!

En la publicación de hoy, demostraré cómo usar secuencias en funciones definidas por el usuario, como escalares, con valores de tabla y agregadas. ¿No sabes qué es una SECUENCIA? Descubre más sobre este objeto accediendo al post Trabajar con secuencias en SQL Server

De forma predeterminada, SQL Server no permite que las propiedades NEXT VALUE FOR de la secuencia se utilicen dentro de las funciones, ya que uno de los conceptos de la función es no tener acceso para cambiar datos externos, es decir, fuera del alcance de la función.

Mensaje de error al intentar utilizar SECUENCIA en la función:
Msg 11719, Nivel 15, Estado 1, Procedimiento fncTeste, Línea 13
La función NEXT VALUE FOR no está permitida en restricciones de verificación, objetos predeterminados, columnas calculadas, vistas, funciones definidas por el usuario, agregados definidos por el usuario, tipos de tablas definidas por el usuario, subconsultas, expresiones de tablas comunes, tablas derivadas o declaraciones de devolución.

Al usar el PRÓXIMO VALOR PARA de la secuencia, estamos cambiando la secuencia, aumentando el valor de la secuencia y devolviendo esta información. Por lo tanto, al hacer esto, estamos “eludiendo” e “infringiendo” este concepto de función. Sin embargo, en algunas situaciones esto puede ser necesario, especialmente cuando ya tiene un sistema funcionando en producción y esta característica debe implementarse con la mínima posibilidad de afectar el flujo normal de operación de ese sistema.

Debido a esta necesidad, demostraré cómo usar la secuencia incluso dentro de funciones.

Cómo usar SECUENCIA en funciones

Para poder usar una SECUENCIA dentro de una función, necesitamos crear una VISTA, usando una declaración OPENROWSET, que abrirá una nueva conexión en la instancia, llamará NEXT VALUE FOR en la secuencia y regresará en la vista.

De esta manera, nuestra función estaría realizando una selección simple en una vista, pero en segundo plano estaríamos usando y consumiendo una SECUENCIA.

Creación de secuencia:

IF (OBJECT_ID('dbo.seq_Teste') IS NOT NULL) DROP SEQUENCE dbo.seq_Teste
CREATE SEQUENCE dbo.seq_Teste AS INT
START WITH 1
INCREMENT BY 1
GO

VER creación:

IF (OBJECT_ID('dbo.vwSeq_Teste') IS NOT NULL) DROP VIEW dbo.vwSeq_Teste
GO

CREATE VIEW dbo.vwSeq_Teste
AS
SELECT [Proximo_Valor] FROM OPENROWSET('SQLOLEDB', 'SERVER=localhost;TRUSTED_CONNECTION=yes', 'SET FMTONLY OFF; SELECT NEXT VALUE FOR Database.dbo.seq_Teste AS [Proximo_Valor]')
GO

Creación de funciones:

CREATE FUNCTION dbo.fncTeste()
RETURNS INT
AS BEGIN

	RETURN (SELECT Proximo_Valor FROM dbo.vwSeq_Teste)
	
END
GO

SELECT dbo.fncTeste()

Ejemplo:

SQL Server - Sequence in Function
SQL Server: secuencia en función

¡Eso es todo, amigos!
Espero que te haya gustado este consejo. No recomiendo usarlo a diario, pero dependiendo de la situación, podría ser un consejo que salve vidas... jajaja

¡Abrazo!