T-SQL CREATE FUNCTION
を使用して、SQL Serverでマルチステートメントテーブル値関数(MSTVF)を作成できます。 構文。
構文
マルチステートメントTVFの公式構文は次のとおりです。
CREATE [ OR ALTER ] FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] [READONLY] } [ ,...n ] ] ) RETURNS @return_variable TABLE <table_type_definition> [ WITH[ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
例1-基本的なMSTVF
これは、マルチステートメントのテーブル値関数の例です。
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
@pets
を指定すると、最初に戻りテーブルの構造が定義されます。 変数。クエリ結果は@pets
に挿入されます 変数。
この場合、関数は引数としてペット名を渡す必要があります。次に、関連するデータを返すために、クエリでこの引数を使用します。 マルチであること -ステートメントテーブル値関数。関数の定義に複数のステートメントを含めることができます。
例2–スキーマバインディングの追加
通常は、SCHEMABINDING
を使用して関数をスキーマバインドすることをお勧めします。 口論。
これを行うと、関数に影響を与えるような方法で基になるテーブルを変更できないようになります。
スキーマバインディングがないと、基になるテーブルが変更されたり、削除されたりする可能性があります。これを行うと、機能が損なわれる可能性があります。
これは同じ関数ですが、今回はスキーマバインディングを使用します:
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
クエリでテーブルを参照するときに2つの部分からなる名前を使用したことに注意してください(dbo.Cats
を使用しました) およびdbo.Dogs
Cats
だけでなく、テーブルを参照する場合 またはDogs
)。これを行うことは、オブジェクトをバインドするスキーマの要件です。 2つの部分からなる名前を使用せずにオブジェクトをスキーマバインドしようとすると、エラーが発生します。
関数をスキーマバインドしたので、その定義で参照されているテーブルを削除しようとすると、エラーが発生します:
DROP TABLE Dogs;
結果:
Msg 3729, Level 16, State 1, Line 1 Cannot DROP TABLE 'Dogs' because it is being referenced by object 'udf_PetsByName_MSTVF'.
ちなみに、2つの部分からなる名前を使用せずに関数を作成しようとすると、次のようになります。
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
結果:
Msg 4512, Level 16, State 3, Procedure udf_PetsByName_MSTVF, Line 10 Cannot schema bind table valued function 'dbo.udf_PetsByName_MSTVF' because name 'Cats' is invalid for schema binding. Names must be in two-part format and an object cannot reference itself.
例3–暗号化の追加
ENCRYPTION
を使用して関数を暗号化することもできます 口論。
関数を暗号化する例を次に示します。
CREATE FUNCTION dbo.udf_PetsByName_MSTVF( @PetName varchar(70)) RETURNS @pets TABLE ( PetId varchar(20), PetName varchar(70) ) WITH SCHEMABINDING, ENCRYPTION AS BEGIN INSERT INTO @pets SELECT CONCAT('Cat', ' ', CatId), CatName FROM dbo.Cats WHERE CatName = @PetName; INSERT INTO @pets SELECT CONCAT('Dog', ' ', DogId), DogName FROM dbo.Dogs WHERE DogName = @PetName; IF @@ROWCOUNT = 0 BEGIN INSERT INTO @pets VALUES ( '', 'There are no pets of that name.' ) END RETURN; END; GO
関数の定義を表示できなくなりました。
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('udf_PetsByName_MSTVF');
結果:
+--------------+ | definition | |--------------| | NULL | +--------------+
Azure Data Studioを介して関数の定義をスクリプト化しようとすると、エラーメッセージも表示されます。
No script was returned when scripting as Create on object UserDefinedFunction
暗号化された関数のテキストは、DACポートを介してシステムテーブルにアクセスするか、データベースファイルに直接アクセスできる特権ユーザーが引き続き利用できることに注意してください。また、デバッガーをサーバープロセスに接続できるユーザーは、実行時にメモリから元のプロシージャを取得できます。