スカラー値の関数に選択ではなく実行権限が必要なのはなぜですか?


15

スカラー値関数の場合、選択だけでなく実行をユーザーに許可しなければならないのはなぜだろうか?

一方、テーブル値関数は、選択権限またはdb_datareaderメンバーシップのみで問題なく機能します。

ここでより明確にするのは私の例です:データベースへの読み取り専用権限を持つユーザーが必要です。という名前のユーザーを作成し、メンバーシップtestUserを付与しdb_datareaderます。次に、というテーブル値関数を作成しましたfn_InlineTable。そしてすべてが素晴らしいです。testUserこのSQLを終日実行します

select * from dbo.fn_InlineTable

その後、スカラー関数が必要なので、というスカラー関数を作成しましたfn_ScalarTesttestUserこのSQLを実行できません

Select dbo.fn_ScalarTest(1) 

当然のことながら、実行するための "testUser"アクセス許可を与えていないためfn_ScalarTestです。

私の質問は次のとおりです:このリンクに基づいて/programming/6150888/insert-update-delete-with-function-in-sql-serverFUNCTIONデータベースの状態を変更するアクションを実行するために使用することはできません。では、実行許可ではなく、同じ「SELECT」許可でスカラー関数を使用させないのはなぜですか?

私の質問が理にかなっていることを願っています。ありがとうございました。

回答:


15

おそらく、主な理由は、テーブルとビューのように、テーブル値関数が結果セットを返すことです。これは、それらが使用できることを意味するFROM(含む句JOINSおよびAPPLYS、等)のSELECTUPDATEおよびDELETEクエリ。ただし、これらのコンテキストでScalar UDFを使用することはできません。

第二に、EXECUTEスカラーUDF も使用できます。この構文は、入力パラメーターにデフォルト値が指定されている場合に非常に便利です。たとえば、次のUDFを使用します。

CREATE FUNCTION dbo.OptionalParameterTest (@Param1 INT = 1, @Param2 INT = 2)
RETURNS INT
AS
BEGIN
    RETURN @Param1 + @Param2;
END;

入力パラメータのいずれかを「オプション」として扱いたい場合DEFAULTは、シグネチャが修正されるため、関数のように呼び出すときにキーワードを渡す必要があります。

DECLARE @Bob1 INT;

SET @Bob1 = dbo.OptionalParameterTest(100, DEFAULT);

SELECT @Bob1;
-- Returns: 102

一方、EXECUTE関数を使用する場合は、ストアドプロシージャの場合と同様に、デフォルト値を持つパラメーターをオプションとして扱うことができます。パラメーター名を指定せずに、最初のn個のパラメーターを渡すことができます。

DECLARE @Bob2 INT;

EXEC @Bob2 = dbo.OptionalParameterTest 50;

SELECT @Bob2;
-- Returns: 52

ストアドプロシージャの場合と同様に、パラメータ名を指定して最初のパラメータをスキップすることもできます。

DECLARE @Bob3 INT;

EXEC @Bob3 = dbo.OptionalParameterTest @Param2 = 50;

SELECT @Bob3;
-- Returns: 51

更新

なぜEXECストアドプロシージャのように構文を使用してスカラーUDFを呼び出したいのでしょうか?UDFがクエリに追加され、返された行のセットを操作できるため、UDFとして優れている場合がありますが、コードがストアドプロシージャにある場合は、カーソルに配置する必要があります。行のセットを反復処理します。しかし、その場合は、おそらく別のUDF内から単一の値でその関数を呼び出したいことがあります。単一の値に対してUDFを呼び出すには、次のいずれかを実行できます。

SELECT dbo.UDF('some value');

その場合、結果セットで戻り値を取得します(結果セットは機能しません)。または、次のように実行できます。

DECLARE @Dummy INT;

SET @Dummy = dbo.UDF('some value');

その場合、@Dummy変数を宣言する必要があります。

ただし、EXEC構文を使用すると、これらの煩わしさの両方を回避できます。

EXEC dbo.UDF 'some value';

また、スカラーUDFには実行プランがキャッシュされています。これは、実行計画のあるクエリがUDFにある場合、パラメータスニッフィングの問題が発生する可能性があることを意味します。EXEC構文を使用することが適切なシナリオでは、WITH RECOMPILEオプションを使用して、その実行用にコンパイルされたプランを無視することもできます。例えば:

セットアップ:

GO
CREATE FUNCTION dbo.TestUDF (@Something INT)
RETURNS INT
AS 
BEGIN
   DECLARE @Ret INT;
   SELECT @Ret = COUNT(*)
   FROM   sys.indexes si
   WHERE  si.[index_id] = @Something;

   RETURN @Ret;
END;
GO

テスト:

DECLARE @Val INT;

SET @Val = dbo.TestUDF(1);
SELECT @Val;

EXEC @Val = dbo.TestUDF 0 -- uses compiled value of (1)
SELECT @Val;

EXEC @Val = dbo.TestUDF 0 WITH RECOMPILE; -- uses compiled value of (0)
SELECT @Val;

EXEC @Val = dbo.TestUDF 3 -- uses compiled value of (1)
SELECT @Val;

4

権限の違いは、ストアドプロシージャと同じようにEXECでスカラー値のユーザー定義関数を実際に呼び出すことができるからだと思います(SQL Server 2000 Books Onlineを掘り下げてユーザー定義関数を導入するまで気づかなかった) 、まだそれらからテーブルソースとして選択することはできません。例えば:

DECLARE @date datetime
EXEC @date = dbo.first_day_of_month '8/14/2015'
SELECT @date

この場合、dbo.first_day_of_monthはユーザー定義関数です。なぜそのように関数を呼び出すのかはわかりませんが、一貫性を維持するためにSELECTではなくEXECUTE権限が必要であると推測します。最近では、おそらく互換性の手荷物として保持しているだけでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.