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ポートを介してシステムテーブルにアクセスするか、データベースファイルに直接アクセスできる特権ユーザーが引き続き利用できることに注意してください。また、デバッガーをサーバープロセスに接続できるユーザーは、実行時にメモリから元のプロシージャを取得できます。