1

Sql Server 2008 R2

我在两个模式中有一个名称相同的视图。当应用程序调用根据用户或用户角色引用视图的存储过程时,我能否自动让应用程序使用其中一个或另一个?

例如,这两个视图被命名为 dbo.Customers 和 production.Customers。每个视图都生成相同的选择列表,但连接到不同的表并具有不同的 WHERE 条件。存储过程当前引用 dbo.Customers。

(注意:实际上有几十个这样的二模式视图,它们被用于数百个存储过程、函数和动态生成的 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 回答