När du skapar en användardefinierad funktion i SQL Server har du möjlighet att kryptera den.
För att skapa en användardefinierad funktion med T-SQL använder du CREATE FUNCTION
syntax. För att kryptera den lägger du till WITH ENCRYPTION
argument.
Du kan också använda samma argument för att kryptera en befintlig funktion när du använder ALTER FUNCTION
.
När du krypterar en användardefinierad funktion på detta sätt konverteras funktionens text till ett obfuskerat format. Funktionens definition är inte direkt synlig i några katalogvyer. Därför kan funktionens definition inte ses av användare som inte har tillgång till systemtabeller eller databasfiler.
Exempel 1 – Inline tabellvärderad funktion med kryptering
Här är ett exempel på hur du skapar en krypterad användardefinierad funktion med tabellvärde.
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
Delen för att kryptera den är WITH ENCRYPTION
. Jag kunde helt enkelt ta bort det argumentet om jag inte ville kryptera det.
Efter att ha skapat den funktionen, nu när jag använder sys.sql_modules
systemkatalogvy för att se dess definition får jag NULL.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');
Resultat:
+--------------+ | definition | |--------------| | NULL | +--------------+
Och här är felmeddelandet jag får i Azure Data Studio när jag försöker skripta funktionen:
No script was returned when scripting as Create on object UserDefinedFunction
Och jag skulle få ett liknande meddelande om jag försökte visa det i SSMS, DBeaver eller någon annan programvara för GUI-databashantering.
Exempel 2 – Multi-Statement Tabell-värderad funktion med kryptering
Här är en TVF med flera påståenden som gör samma sak som den tidigare funktionen. TVF:er med flera uttalanden har en annan syntax än inline-TVF:er. På TVF:er med flera uttalanden sätter du krypteringsalternativet efter att du har angett returvariabeln.
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
Exempel 3 – Skalär funktion med kryptering
Och här är ett exempel på en krypterad skalär funktion:
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
Exempel 4 – Lägg till kryptering till en befintlig funktion
Om du vill kryptera en befintlig funktion, använd ALTER FUNCTION
med samma definition. Med andra ord kan jag ta det första exemplet och ersätta CREATE
med 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
Detta förutsätter uppenbarligen att resten av funktionens definition är exakt densamma som den befintliga funktionen.
Det enklaste sättet att säkerställa att du använder samma definition är att använda ditt GUI-verktyg för att skripta den befintliga funktionen med alternativet "Script as Alter", om det finns. Annars kan du använda "Skript som Skapa", och sedan ändra CREATE
när definitionen visas med ALTER
.
Om du bara har ett kommandoradsgränssnitt kan du fråga sys.sql_modules
visa för att få den befintliga definitionen (som i föregående exempel). Du kan sedan kopiera definitionen och ersätta CREATE
med ALTER
.
När du har gjort det kan du lägga till WITH ENCRYPTION
och kör det igen.
Exempel 5 – Lägga till flera argument
Du kan ange flera argument som en kommaseparerad lista. Till exempel, om du vill använda kryptering och du vill ange schemabindning måste du lägga till dessa som en kommaseparerad lista.
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
Med andra ord, du anger bara WITH
en gång – du behöver inte upprepa det för varje argument.
Viktiga anmärkningar
Här är några saker du bör veta om att kryptera användardefinierade funktioner i SQL Server:
- Privilegerade användare som kan komma åt systemtabeller via DAC-porten eller direkt komma åt databasfiler kommer fortfarande att kunna se funktionens (icke-krypterade) definition.
- Användare som kan koppla en debugger till serverprocessen kan hämta den ursprungliga proceduren från minnet vid körning.
- Användning av kryptering förhindrar att funktionen publiceras som en del av SQL Server-replikering.
- CLR-funktioner kan inte krypteras.