SQL Server 可以根据用户或用户角色在两个架构之间进行仲裁吗?
Posted
技术标签:
【中文标题】SQL Server 可以根据用户或用户角色在两个架构之间进行仲裁吗?【英文标题】:Can SQL Server arbitrate between two schemas based on the user or user's role? 【发布时间】:2012-11-10 18:28:29 【问题描述】:Sql Server 2008 R2
我在两个模式中有一个名称相同的视图。当应用程序根据用户或用户的角色调用引用视图的存储过程时,我能否自动让应用程序使用其中一个或另一个?
例如这两个视图名为 dbo.Customers 和 production.Customers。每个视图都生成相同的选择列表,但连接到不同的表并具有不同的 WHERE 条件。存储过程当前引用 dbo.Customers。
(注意:实际上有几十个这样的二模式视图,它们用于数百个存储过程、函数和动态生成的 sql。重写所有这些都需要数年时间)
【问题讨论】:
【参考方案1】:存储过程(模块)中的对象名称是resolved based on the owner of the stored procedure(模块)而不是执行用户。因此,如果您在声明为的存储过程中引用名为 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;
就我个人而言,我不太喜欢这种模式的使用。模式是为了安全,在较小程度上是为了避免大量数据库对象的名称冲突。我个人更喜欢将每组对象放在不同的数据库中,并使用默认数据库的不同用户登录来控制名称解析。
【讨论】:
以上是关于SQL Server 可以根据用户或用户角色在两个架构之间进行仲裁吗?的主要内容,如果未能解决你的问题,请参考以下文章
用户组或角色 'zgb' 在当前数据库中已存在。 (Microsoft SQL Server,错误: 15023)