読み取り権限のみのユーザーを使用しています。基本的には
ただし、関数とストアドプロシージャに対する実行権限はありません。一部のレポートでは、自分の関数を呼び出しています。 SP、関数、ビューを実行するreadonlyuser
権限を与えたいのですが。
私は このコード に遭遇しました。これは、特定のユーザーにストアドプロシージャと関数の実行権限を与える方法を示しています。
- Grant Execute on all functions for testuser
declare @username varchar(255)
set @username = 'testuser'
SELECT 'grant exec on ' + QUOTENAME(ROUTINE_SCHEMA) + '.' +
QUOTENAME(ROUTINE_NAME) + ' TO ' + @username FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(ROUTINE_NAME),'IsMSShipped') = 0
and ROUTINE_TYPE='PROCEDURE'
および関数
declare @username varchar(255)
set @username = 'testuser'
SELECT 'grant exec on ' + QUOTENAME(ROUTINE_SCHEMA) + '.' +
QUOTENAME(ROUTINE_NAME) + ' TO ' + @username FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(ROUTINE_NAME),'IsMSShipped') = 0
and ROUTINE_TYPE='FUNCTION'
さて、ここでは既存のSPおよび関数のみにこの権限が適用されているようです。新しい関数を追加する場合は、このコードを再度実行して権限を付与する必要があります。
上記の解釈が間違っていない場合、読み取り専用ユーザーに実行権限を付与して、新しい関数を作成した場合でも、すべての関数とストアドプロシージャに対する権限を付与する方法はありますか?
ビューに同じ権限を適用できますか?
this thread では、テーブルを返す関数に実行権限を与えることができないと言われています。本当?
いくつか質問があることは知っていますが、それらはすべて関連しています。 1つの場所にいる方がよい。
テーブルを返す関数にEXEC
権限を付与できないのは事実です。このタイプの関数は、実際には関数というよりビューです。代わりにSELECTを付与する必要があります。例:
_GRANT SELECT ON dbo.Table_Valued_Function TO [testuser];
_
したがって、スクリプトは次のようになります(申し訳ありませんが、 私は_INFORMATION_SCHEMA
_ を絶対に嫌っています。また、OBJECTPROPERTY
などの関数を必要としないカタログビューを使用することをお勧めします。 ):
_DECLARE
@sql NVARCHAR(MAX) = N'',
@username VARCHAR(255) = 'testuser';
SELECT @sql += CHAR(13) + CHAR(10) + N'GRANT ' + CASE
WHEN type_desc LIKE 'SQL_%TABLE_VALUED_FUNCTION'
OR type_desc = 'VIEW'
THEN ' SELECT ' ELSE ' EXEC ' END
+ ' ON ' + QUOTENAME(SCHEMA_NAME([schema_id]))
+ '.' + QUOTENAME(name)
+ ' TO ' + @username + ';'
FROM sys.all_objects
WHERE is_ms_shipped = 0 AND
(
type_desc LIKE '%PROCEDURE'
OR type_desc LIKE '%FUNCTION'
OR type_desc = 'VIEW'
);
PRINT @sql;
-- EXEC sp_executesql @sql;
_
これで、スキーマにEXEC
を付与し、そのスキーマでこれらのプロシージャを作成できます(実際にはスキーマの目的の1つです)。これは、@ jgardner04ですでに提案されていますが、このソリューションをテーブルに適用するには、値のある関数も同様に、SELECT
も付与する必要があります。そのスキーマのテーブルにデータを保存しない場合(または少なくとも非表示にする場合)は問題ありませんが、意図していない可能性があるすべてのテーブルとビューにも適用されます。
別のアイデア(たとえば、スキーマを使用できない、または使用したくない場合)は、_CREATE_PROCEDURE
_、_CREATE_FUNCTION
_および_CREATE_VIEW
_イベントをキャプチャするDDLトリガーを作成し、許可することです。ユーザー(または、テーブルに格納する場合は、ユーザーのセット)に対する権限:
_CREATE TRIGGER ApplyPermissionsToAllProceduressAndFunctions -- be more creative!
ON DATABASE FOR CREATE_PROCEDURE, CREATE_FUNCTION, CREATE_VIEW
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@sql NVARCHAR(MAX),
@EventData XML = EVENTDATA();
;WITH x ( sch, obj )
AS
(
SELECT
@EventData.value('(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(255)'),
@EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(255)')
)
SELECT @sql = N'GRANT ' + CASE
WHEN o.type_desc LIKE 'SQL_%TABLE_VALUED_FUNCTION'
OR o.type_desc = 'VIEW'
THEN ' SELECT '
ELSE ' EXEC ' END
+ ' ON ' + QUOTENAME(x.sch)
+ '.' + QUOTENAME(x.obj)
+ ' TO testuser;' -- hard-code this, use a variable, or store in a table
FROM x
INNER JOIN sys.objects AS o
ON o.[object_id] = OBJECT_ID(QUOTENAME(x.sch) + '.' + QUOTENAME(x.obj));
EXEC sp_executesql @sql;
END
GO
_
私がDDLトリガーで見つけた欠点は、それらがそこにあることをすぐに忘れることができることです。したがって、すべての新しいオブジェクトへのこれらのアクセス許可の付与をやめることに決めた1年後、それがまだ起こっている理由のトラブルシューティングには時間がかかる場合があります。私の最後の仕事では、DDLトリガーによって呼び出されたすべてのアクションを一種の中央の「イベントログ」に記録しました。これは、誰も覚えていないようにサーバーで発生したアクションを追跡するための最適な場所でした(そしてそれはDDLは約半分の時間でトリガーされます)。そのため、これに役立つロジックをいくつか追加することを検討してください。
[〜#〜]編集[〜#〜]
スキーマベースのコードを追加します。これにより、fooスキーマで作成されたすべてのプロシージャ、関数、およびテーブルへのアクセス許可が付与されることを再度説明します。
_CREATE SCHEMA foo;
GRANT EXEC, SELECT ON SCHEMA::foo TO testuser;
_
次のプロシージャを作成すると、testuserを実行できるようになります。
_CREATE PROCEDURE foo.proc1
AS
BEGIN
SET NOCOUNT ON;
SELECT 1;
END
GO
_
スキーマを利用して、スキーマ内のアイテムを実行する権限をユーザーに付与できますか?スキーマに関する詳細情報は、ここにあります: http://msdn.Microsoft.com/en-us/library/ms187940.aspx