Quando si crea una funzione definita dall'utente in SQL Server, è possibile crittografarla.
Per creare una funzione definita dall'utente con T-SQL, si utilizza CREATE FUNCTION
sintassi. Per crittografarlo, aggiungi il WITH ENCRYPTION
argomento.
Puoi anche usare lo stesso argomento per crittografare una funzione esistente quando usi ALTER FUNCTION
.
Quando si crittografa una funzione definita dall'utente in questo modo, il testo della funzione viene convertito in un formato offuscato. La definizione della funzione non è direttamente visibile in nessuna vista del catalogo. Pertanto, la definizione della funzione non può essere visualizzata dagli utenti che non hanno accesso alle tabelle di sistema o ai file di database.
Esempio 1 – Funzione inline con valori di tabella con crittografia
Ecco un esempio di creazione di una funzione crittografata con valori di tabella definita dall'utente.
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 per la crittografia è WITH ENCRYPTION
. Potrei semplicemente rimuovere quell'argomento se non volessi crittografarlo.
Dopo aver creato quella funzione, ora quando uso sys.sql_modules
vista del catalogo di sistema per visualizzarne la definizione, ottengo NULL.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');
Risultato:
+--------------+ | definition | |--------------| | NULL | +--------------+
Ed ecco il messaggio di errore che ricevo in Azure Data Studio quando provo a eseguire lo script della funzione:
No script was returned when scripting as Create on object UserDefinedFunction
E otterrei un messaggio simile se provassi a visualizzarlo in SSMS, DBeaver o qualsiasi altro software di gestione del database della GUI.
Esempio 2 – Funzione con valori di tabella a più istruzioni con crittografia
Ecco un TVF multi-istruzione che fa lo stesso della funzione precedente. I TVF a più istruzioni hanno una sintassi diversa rispetto ai TVF in linea. Su TVF a più istruzioni, inserisci l'opzione di crittografia dopo aver specificato la variabile di ritorno.
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
Esempio 3 – Funzione scalare con crittografia
Ed ecco un esempio di una funzione scalare crittografata:
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
Esempio 4:aggiunta della crittografia a una funzione esistente
Se vuoi crittografare una funzione esistente, usa ALTER FUNCTION
con la stessa definizione. In altre parole, posso prendere il primo esempio e sostituire 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
Ciò ovviamente presuppone che il resto della definizione della funzione sia esattamente la stessa della funzione esistente.
Il modo più semplice per assicurarti di utilizzare la stessa definizione è utilizzare lo strumento GUI per eseguire lo script della funzione esistente utilizzando l'opzione "Script as Alter", se esiste. Altrimenti potresti usare "Script come Crea", quindi quando appare la definizione, cambia CREATE
con ALTER
.
Se hai solo un'interfaccia a riga di comando, puoi interrogare sys.sql_modules
view per ottenere la definizione esistente (come nell'esempio precedente). Puoi quindi copiare la definizione e sostituire CREATE
con ALTER
.
Dopo averlo fatto, puoi aggiungere WITH ENCRYPTION
ed eseguilo di nuovo.
Esempio 5 – Aggiunta di più argomenti
È possibile specificare più argomenti come un elenco separato da virgole. Ad esempio, se desideri utilizzare la crittografia e vuoi specificare il binding dello schema, quindi dovresti aggiungerli come un elenco separato da virgole.
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
In altre parole, specifichi solo WITH
una volta – non c'è bisogno di ripeterlo per ogni argomento.
Note importanti
Ecco alcune cose che dovresti sapere sulla crittografia delle funzioni definite dall'utente in SQL Server:
- Gli utenti privilegiati che possono accedere alle tabelle di sistema tramite la porta DAC o accedere direttamente ai file del database potranno comunque visualizzare la definizione della funzione (non crittografata).
- Gli utenti che possono collegare un debugger al processo del server possono recuperare la procedura originale dalla memoria in fase di esecuzione.
- L'uso della crittografia impedisce la pubblicazione della funzione come parte della replica di SQL Server.
- Le funzioni CLR non possono essere crittografate.