ストアド プロシージャ (モジュール) 内のオブジェクト名は、実行ユーザーではなく、ストアド プロシージャ (モジュール) の所有者に基づいて解決されます。したがって、次のように宣言されたストアド プロシージャ内で 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;
個人的には、このようなスキーマの使用はあまり好きではありません。スキーマはセキュリティのためのもので、程度は低いですが、多数のデータベース オブジェクトの名前の衝突を回避します。個人的には、オブジェクトの各セットを異なるデータベースに配置し、既定のデータベースで異なるユーザー ログインを使用して名前解決を制御することを好みます。