Podczas tworzenia funkcji zdefiniowanej przez użytkownika w SQL Server masz możliwość jej zaszyfrowania.
Aby utworzyć funkcję zdefiniowaną przez użytkownika za pomocą T-SQL, użyj CREATE FUNCTION
składnia. Aby go zaszyfrować, dodaj WITH ENCRYPTION
argument.
Możesz również użyć tego samego argumentu do zaszyfrowania istniejącej funkcji podczas korzystania z ALTER FUNCTION
.
Gdy szyfrujesz funkcję zdefiniowaną przez użytkownika w ten sposób, tekst funkcji jest konwertowany na format zaciemniony. Definicja funkcji nie jest bezpośrednio widoczna w żadnych widokach katalogowych. Dlatego definicja funkcji nie może być przeglądana przez użytkowników, którzy nie mają dostępu do tabel systemowych ani plików baz danych.
Przykład 1 — Wbudowana funkcja z wartościami tabelarycznymi z szyfrowaniem
Oto przykład tworzenia zaszyfrowanej, zdefiniowanej przez użytkownika funkcji o wartościach w tabeli.
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
Część do zaszyfrowania to WITH ENCRYPTION
. Mógłbym po prostu usunąć ten argument, gdybym nie chciał go zaszyfrować.
Po utworzeniu tej funkcji, teraz kiedy używam sys.sql_modules
widok katalogu systemowego, aby wyświetlić jego definicję, otrzymuję NULL.
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_CatsByName_ITVF');
Wynik:
+--------------+ | definition | |--------------| | NULL | +--------------+
A oto komunikat o błędzie, który pojawia się w Azure Data Studio, gdy próbuję napisać funkcję:
No script was returned when scripting as Create on object UserDefinedFunction
Otrzymałbym podobny komunikat, gdybym spróbował wyświetlić go w SSMS, DBeaver lub innym oprogramowaniu do zarządzania bazą danych GUI.
Przykład 2 – Wielowyrazowa funkcja z wartościami tabelarycznymi z szyfrowaniem
Oto wielowyrazowy TVF, który robi to samo, co poprzednia funkcja. Wieloinstrukcyjne pliki TVF mają inną składnię niż wbudowane pliki TVF. W przypadku wielostanowiskowych plików TVF umieszczasz opcję szyfrowania po określeniu zmiennej zwracanej.
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
Przykład 3 – Funkcja skalarna z szyfrowaniem
A oto przykład zaszyfrowanej funkcji skalarnej:
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
Przykład 4 – Dodaj szyfrowanie do istniejącej funkcji
Jeśli chcesz zaszyfrować istniejącą funkcję, użyj ALTER FUNCTION
z tą samą definicją. Innymi słowy, mogę wziąć pierwszy przykład i zastąpić CREATE
z 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
To oczywiście zakłada, że reszta definicji funkcji jest dokładnie taka sama jak istniejąca funkcja.
Najprostszym sposobem na upewnienie się, że używasz tej samej definicji, jest użycie narzędzia GUI do skryptu istniejącej funkcji za pomocą opcji „Skrypt jako zmiana”, jeśli istnieje. W przeciwnym razie możesz użyć „Skrypt jako Utwórz”, a gdy pojawi się definicja, zmień CREATE
z ALTER
.
Jeśli masz tylko interfejs wiersza poleceń, możesz zapytać sys.sql_modules
widok, aby uzyskać istniejącą definicję (jak w poprzednim przykładzie). Następnie możesz skopiować definicję i zastąpić CREATE
z ALTER
.
Gdy to zrobisz, możesz dodać WITH ENCRYPTION
i uruchom go ponownie.
Przykład 5 – Dodawanie wielu argumentów
Możesz podać wiele argumentów jako listę rozdzielaną przecinkami. Na przykład, jeśli chcesz używać szyfrowania i chcesz określić powiązanie schematu, musisz dodać je jako listę oddzieloną przecinkami.
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
Innymi słowy, określasz tylko WITH
raz – nie trzeba powtarzać tego dla każdego argumentu.
Ważne uwagi
Oto kilka rzeczy, które powinieneś wiedzieć o szyfrowaniu funkcji zdefiniowanych przez użytkownika w SQL Server:
- Uprawnieni użytkownicy, którzy mogą uzyskiwać dostęp do tabel systemowych przez port DAC lub bezpośrednio uzyskiwać dostęp do plików bazy danych, nadal będą mogli wyświetlać (niezaszyfrowaną) definicję funkcji.
- Użytkownicy, którzy mogą dołączyć debuger do procesu serwera, mogą pobrać oryginalną procedurę z pamięci w czasie wykonywania.
- Korzystanie z szyfrowania uniemożliwia opublikowanie funkcji w ramach replikacji programu SQL Server.
- Funkcje CLR nie mogą być szyfrowane.