1

SQL Server 2008 R2

2つのスキーマで同じ名前のビューがあります。ユーザーまたはユーザーの役割に応じてビューを参照するストアドプロシージャを呼び出すときに、アプリケーションにどちらか一方を自動的に使用させることはできますか?

たとえば、2つのビューの名前はdbo.Customersとproduction.Customersです。各ビューは同じ選択リストを生成しますが、異なるテーブルへの結合があり、異なるWHERE基準があります。ストアドプロシージャは現在、dbo.Customersを参照しています。

(注:これらの2つのスキーマビューは実際には数十あり、数百のストアドプロシージャ、関数、および動的に生成されたSQLで使用されます。すべてを書き直すには何年もかかります)

4

1 に答える 1

0

ストアド プロシージャ (モジュール) 内のオブジェクト名は、実行ユーザーではなく、ストアド プロシージャ (モジュール) の所有者に基づいて解決されます。したがって、次のように宣言されたストアド プロシージャ内で TABLE_1 というテーブルを参照するとします。

CREATE PROCEDURE dbo.usp_GetTable_1 AS SELECT * FROM [TABLE_1]

解決されたテーブル名は [dbo].[TABLE_1] になります。

動的 SQL を使用する場合は、次のようにすることができます。

--Stored procedure uses dynamic SQL so object name resolution rules inside
--modules does not apply
CREATE PROCEDURE dbo.usp_GetTable_1 AS 
  EXEC sp_executesql N'SELECT * FROM [TABLE_1]'
GO

--create Table_1 in two schemas
CREATE TABLE [Com1].[Table_1](
    [Id] [int] NOT NULL,
    [Schema] As OBJECT_SCHEMA_NAME ( OBJECT_ID('[Com1].[Table_1]' ))
) ON [PRIMARY]

GO
CREATE TABLE [Com2].[Table_1](
    [Id] [int] NOT NULL,
    [Schema] As OBJECT_SCHEMA_NAME ( OBJECT_ID('[Com2].[Table_1]' ))
) ON [PRIMARY]
GO

--Now create two users, defaulting each to one of the schemas
CREATE USER Com1User WITHOUT LOGIN WITH default_schema = [Com1]
CREATE USER Com2User WITHOUT LOGIN WITH default_schema = [Com2]

--set the ownership of the schemas to match
ALTER AUTHORIZATION ON SCHEMA::[Com1] TO [Com1User]
ALTER AUTHORIZATION ON SCHEMA::[Com2] TO [Com2User]

--Adding the users to the db_owner role naively allows executing dbo schema modules
--for demo purposes. Alternatively grant execution to specific dbo modules 
EXEC sp_addrolemember N'db_owner', N'Com1User'
EXEC sp_addrolemember N'db_owner', N'Com2User'

--Set the execution context and call the procedure
EXECUTE AS User = 'Com1User'
EXEC dbo.usp_GetTable_1
REVERT;

--Set the execution context and call the procedure
EXECUTE AS User = 'Com2User'
EXEC dbo.usp_GetTable_1
REVERT;

個人的には、このようなスキーマの使用はあまり好きではありません。スキーマはセキュリティのためのもので、程度は低いですが、多数のデータベース オブジェクトの名前の衝突を回避します。個人的には、オブジェクトの各セットを異なるデータベースに配置し、既定のデータベースで異なるユーザー ログインを使用して名前解決を制御することを好みます。

于 2012-12-12T05:10:06.197 に答える