sql >> Base de Datos >  >> RDS >> Sqlserver

Crear una función escalar definida por el usuario en SQL Server

En SQL Server, puede crear una función escalar definida por el usuario usando CREATE FUNCTION declaración. Una función escalar definida por el usuario, también conocida como UDF escalar, es una función definida por el usuario que devuelve un único valor.

Este artículo contiene ejemplos de cómo crear algunas UDF escalares de T-SQL básicas.

Sintaxis

Primero, veamos la sintaxis para crear UDF escalares.

La sintaxis de las UDF escalares de T-SQL es la siguiente:

 
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type   
    [ = default ] [ READONLY ] }   
    [ ,...n ]  
  ]  
)  
RETURNS return_data_type  
    [ WITH <function_option> [ ,...n ] ]  
    [ AS ]  
    BEGIN   
        function_body   
        RETURN scalar_expression  
    END  
[ ; ]

Y la sintaxis para las UDF escalares de CLR:

 
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name   
( { @parameter_name [AS] [ type_schema_name. ] parameter_data_type   
    [ = default ] }   
    [ ,...n ]  
)  
RETURNS { return_data_type }  
    [ WITH <clr_function_option> [ ,...n ] ]  
    [ AS ] EXTERNAL NAME   
[ ; ]  

Las partes en <function_option> para funciones T-SQL y <clr_function_option> para las funciones CLR le permiten especificar opciones para la UDF. Las opciones de función incluyen agregar cifrado, enlace de esquema, un EXECUTE AS cláusula, además de especificar qué hacer cuando se pasa un valor NULL como argumento.

Puede encontrar una lista completa de argumentos y opciones de funciones en el sitio web de Microsoft.

La documentación de Microsoft contiene muchos detalles, por lo que los siguientes ejemplos tienen como objetivo proporcionar una descripción general rápida de algunos conceptos y opciones comunes al crear UDF escalares.

Ejemplo 1:UDF escalar básico

Este es un ejemplo del código utilizado para crear una UDF escalar T-SQL básica.

CREATE FUNCTION dbo.ufn_discountPrice( 
    @price DECIMAL(12,2), 
    @discount DECIMAL(12,2) 
    ) 
RETURNS DECIMAL (12,2)
AS
BEGIN
  RETURN @price * (1 - @discount);
END;

Esta UDF escalar acepta dos parámetros; @price y @discount . Estos se pasan a la función como argumentos cada vez que se invoca la función. La función toma el valor de esos argumentos, realiza un cálculo usando esos valores y luego devuelve el valor resultante. En este caso, se devuelve el precio con descuento.

Ejemplo 2:invocar la UDF

Una vez que se ha creado el UDF, se puede invocar dentro del código T-SQL en cualquier momento que lo necesite.

Este es un ejemplo de cómo invocar la UDF:

SELECT dbo.ufn_discountPrice(100, .2) AS Result;

Resultado

+----------+
| Result   |
|----------|
| 80.00    |
+----------+

Ejemplo 3:consulta de una tabla

Las UDF escalares también pueden hacer cosas como consultar tablas de bases de datos.

Aquí hay uno que devuelve la cantidad de álbumes que hay en la base de datos para un artista determinado.

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Esta es una función escalar porque devuelve un solo valor. Si quisiéramos devolver una lista de álbumes, necesitaríamos usar una función con valores de tabla, porque las funciones con valores de tabla devuelven sus resultados como un conjunto de filas.

Ejemplo 4:enlace de esquema

Cuando crea una función definida por el usuario que depende de otros objetos en la base de datos, generalmente es una buena idea vincular el esquema a la UDF. El enlace de esquema de la UDF garantiza que no se puedan realizar cambios en los objetos subyacentes que podrían afectar potencialmente a la función.

Por ejemplo, no podría descartar una tabla que utiliza un UDF vinculado a un esquema en su definición.

Para vincular un esquema a una UDF, use WITH SCHEMABINDING en su definición. También debe usar nombres de dos partes para cualquier objeto al que se haga referencia en la UDF.

Aquí está el ejemplo anterior reescrito para que esté vinculado al esquema:

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH SCHEMABINDING
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Entonces, cambié dos cosas del primer ejemplo. Agregué WITH SCHEMABINDING y cambié Albums a dbo.Albums .

Ahora, si alguien intenta eliminar esa tabla o realizar otros cambios en ella, obtendrá un error.

Ejemplo 5:Cifrado

También puede usar WITH ENCRYPTION para cifrar la función.

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH ENCRYPTION
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Ejemplo 6:entrada NULL

Al invocar la función, si alguno de los argumentos es NULL, el cuerpo de la función aún se ejecuta. Es decir, a menos que haya indicado explícitamente RETURNS NULL ON NULL INPUT en la definición de la función.

Especificar esa opción devolverá NULL si alguno de los argumentos es NULL.

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH RETURNS NULL ON NULL INPUT
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Cuando invoco la función usando NULL como argumento:

SELECT dbo.ufn_CountAlbums(NULL) AS Result;

Obtengo un resultado diferente, dependiendo de lo que haya especificado para esta opción.

Aquí está el resultado cuando la función usa la configuración predeterminada (CALLED ON NULL INPUT ):

+----------+
| Result   |
|----------|
| 0        |
+----------+

Y aquí está el resultado cuando usa RETURNS NULL ON NULL INPUT :

+----------+
| Result   |
|----------|
| NULL     |
+----------+

Ejemplo 7:múltiples opciones

Puede separar varias opciones con una coma.

Aquí hay un ejemplo que agrega cifrado y enlace de esquema a la función:

CREATE FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH ENCRYPTION, SCHEMABINDING
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;

Ejemplo 8:modificar una función

Puede modificar una UDF escalar reemplazando CREATE con ALTER .

ALTER FUNCTION dbo.ufn_CountAlbums (@ArtistId int)  
RETURNS smallint
WITH SCHEMABINDING
AS  
BEGIN  
    DECLARE @AlbumCount int;
    SELECT @AlbumCount = COUNT(AlbumId)
    FROM dbo.Albums
    WHERE ArtistId = @ArtistId; 
    RETURN @AlbumCount;
END;