我正在使用ASP.NET MVC,SQL Server,Dapper开发一个多租户应用程序,其中包含单个数据库和每个租户的多个模式.
将为租户分配拥有租户架构的db用户.我在dbo中有一组表,所有模式共享另一组.
说我有dbo.Tenant和anySchema.Table1.从我为anyschema用户设置连接字符串的应用程序,如果我从Table1调用select *,它将返回anySchema.Table1中的值.如果我在存储过程中有相同的查询,它会在尝试访问dbo.Table1时抛出错误.
我为租户db用户提供了dbo的执行访问权限,因为所有租户都在dbo.SP_Name共享单个SP
如何执行以租户db用户身份登录的存储过程,访问anyschema的Table1,以便所有租户都可以使用单个SP.
最佳答案 假设我们的数据库tenant1和tenant2中有两个用户拥有自己的模式(也称为tenant1和tenant2).
我们为每个租户创建一个Contacts表,因此我们有tenant1.Contacts和tenant2.Contacts.
在我们的应用程序中,我们使用Dapper执行以下SQL.我们使用租户特定的连接字符串,该字符串使用租户的SQL Server登录详细信息.
select * from Contacts
由于我们没有在SQL中指定模式,因此它是从执行SQL的用户的默认模式中推断出来的.因此对于tenant1,它将查询tenant1.Contacts,对于tenant2,它将查询tenant2.Contacts.
现在我们将在dbo架构中创建一个执行相同查询的存储过程:
CREATE PROCEDURE GetContacts
AS
BEGIN
select * from Contacts
END
GO
请注意,我没有在存储过程的SQL中指定模式.
当我们从应用程序执行存储过程时,仍然可以从当前用户推断存储过程的模式,但SP中的SQL推断出来自SP的模式.因此,如果SP属于dbo架构,它将对dbo.Contacts表执行查询.
这就是你的情况.您已在dbo架构中创建了一个存储过程,并期望它针对租户的默认架构执行SQL.
你有几个选择
>将架构作为参数传递给存储过程,并使用动态SQL-How to pass schema as parameter to a stored procedure in sql server?
>为每个租户创建一个SP版本,例如tenant1.SP_Name,tenant2.SP_Name
>不要使用存储过程.