Al crear una función definida por el usuario en SQL Server, tiene la opción de cifrarla.
Para crear una función definida por el usuario con T-SQL, utilice CREATE FUNCTION
sintaxis. Para encriptarlo, agrega el WITH ENCRYPTION
argumento.
También puede usar el mismo argumento para cifrar una función existente al usar ALTER FUNCTION
.
Cuando cifra una función definida por el usuario de esta manera, el texto de la función se convierte a un formato ofuscado. La definición de la función no es directamente visible en ninguna vista de catálogo. Por lo tanto, la definición de la función no puede ser vista por usuarios que no tengan acceso a las tablas del sistema o a los archivos de la base de datos.
Ejemplo 1:función con valores de tabla en línea con cifrado
Este es un ejemplo de cómo crear una función cifrada con valores de tabla definida por el usuario.
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE WITH ENCRYPTION AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
La parte para cifrarlo es WITH ENCRYPTION
. Simplemente podría eliminar ese argumento si no quisiera cifrarlo.
Después de crear esa función, ahora cuando uso sys.sql_modules
vista de catálogo del sistema para ver su definición, obtengo NULL.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');
Resultado:
+--------------+ | definition | |--------------| | NULL | +--------------+
Y este es el mensaje de error que recibo en Azure Data Studio cuando intento crear un script para la función:
No script was returned when scripting as Create on object UserDefinedFunction
Y recibiría un mensaje similar si intentara verlo en SSMS, DBeaver o cualquier otro software de administración de base de datos GUI.
Ejemplo 2:función con valores de tabla de declaraciones múltiples con cifrado
Aquí hay un TVF de declaraciones múltiples que hace lo mismo que la función anterior. Los TVF de declaraciones múltiples tienen una sintaxis diferente a los TVF en línea. En los TVF de declaraciones múltiples, coloca la opción de cifrado después de especificar la variable de retorno.
CREATE FUNCTION [dbo].[udf_CatsByName_MSTVF]( @CatName varchar(70) ) RETURNS @cats TABLE ( CatId int, CatName varchar(70), Phone varchar(10) ) WITH ENCRYPTION AS BEGIN INSERT INTO @cats SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName; RETURN; END; GO
Ejemplo 3:función escalar con cifrado
Y aquí hay un ejemplo de una función escalar encriptada:
CREATE FUNCTION dbo.discountPrice( @price DECIMAL(12,2), @discount DECIMAL(12,2) ) RETURNS DECIMAL (12,2) WITH ENCRYPTION AS BEGIN RETURN @price * (1 - @discount); END; GO
Ejemplo 4:agregar cifrado a una función existente
Si desea encriptar una función existente, use ALTER FUNCTION
con la misma definición. En otras palabras, puedo tomar el primer ejemplo y reemplazar CREATE
con ALTER
.
ALTER FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE WITH ENCRYPTION AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
Obviamente, esto supone que el resto de la definición de la función es exactamente igual a la función existente.
La forma más fácil de asegurarse de que está usando la misma definición es usar su herramienta GUI para crear un script de la función existente usando la opción "Script as Alter", si existe. De lo contrario, podría usar "Script como Create", luego, cuando aparezca la definición, cambie CREATE
con ALTER
.
Si solo tiene una interfaz de línea de comandos, puede consultar sys.sql_modules
view para obtener la definición existente (como en el ejemplo anterior). Luego puede copiar la definición y reemplazar CREATE
con ALTER
.
Una vez que haya hecho eso, puede agregar WITH ENCRYPTION
y ejecutarlo de nuevo.
Ejemplo 5:agregar varios argumentos
Puede especificar varios argumentos como una lista separada por comas. Por ejemplo, si desea utilizar el cifrado y desea especificar el enlace de esquema, entonces deberá agregarlos como una lista separada por comas.
CREATE FUNCTION dbo.udf_CatsByName_ITVF( @CatName varchar(70) ) RETURNS TABLE WITH SCHEMABINDING, ENCRYPTION AS RETURN ( SELECT CatId, CatName, Phone FROM dbo.Cats WHERE CatName = @CatName ); GO
En otras palabras, solo especifica WITH
una vez, no es necesario repetirlo para cada argumento.
Notas importantes
Aquí hay algunas cosas que debe saber sobre el cifrado de funciones definidas por el usuario en SQL Server:
- Los usuarios privilegiados que pueden acceder a las tablas del sistema a través del puerto DAC o acceder directamente a los archivos de la base de datos aún podrán ver la definición de la función (no cifrada).
- Los usuarios que pueden adjuntar un depurador al proceso del servidor pueden recuperar el procedimiento original de la memoria en tiempo de ejecución.
- El uso del cifrado evita que la función se publique como parte de la replicación de SQL Server.
- Las funciones CLR no se pueden cifrar.