从具有当前用户架构的表中选择

时间:2013-03-29 21:43:29

标签: sql sql-server tsql stored-procedures database-schema

我在数据库中工作,每个用户的架构中都有一个名为FindResults的表

例如:MyDatabase.User1.FindResults,MyDatabase.User2.FindResults等。

如果我作为其中一个用户登录时在此表上运行SELECT查询,则它可以正常工作。但是,我有一个存储过程(MyDatabase.dbo.ReadFindResults)尝试在此表上运行SELECT查询,它失败,因为它尝试读取MyDatabase.dbo.FindResults(不存在)。我通过使用动态SQL来解决这个问题,但我希望有一种方法可以避免这种情况。

有没有办法告诉存储过程使用当前用户的架构或者某些东西来改变范围以允许它找到我想要的表?

编辑:这是存储过程的代码

-- Returns the IDs contained in the given find results set
CREATE PROCEDURE [dbo].[ReadFindResults]
    @resultsid int  -- The ID of the results set
AS
BEGIN

   SELECT objectid FROM FindResults WHERE resultsid = @resultsid

END
GO 

2 个答案:

答案 0 :(得分:0)

在您的存储过程中,您可以说:

SELECT cols FROM MyDatabase..FindResults;

(退出架构名称。)

然而,这似乎非常容易出错,而IMHO你或者应该有单独的,架构绑定的存储过程,或者是一个带有列的表来指示它是哪一行。

黑客可以作为用户名执行:

DECLARE @sql NVARCHAR(255) = N'EXECUTE AS USER = N''' + SUSER_SNAME() + '''';
EXEC sp_executesql @sql;
SELECT whatever FROM Findresults;

但我没有机会对此进行测试(无论如何,你都能更好地测试你的场景)。

首先它似乎仍然是一个非常可以避免的问题,但也许这只是我。

答案 1 :(得分:0)

您可以像这样使用动态SQL:

DECLARE @sql NVARCHAR(1024) = "SELECT something FROM [userName].someTable"
DECLARE @userName NVARCHAR(255) = SUSER_SNAME()
SET @sql = REPLACE(@sql, "[userName]", @userName)

EXEC sp_executesql @sql

这也是一种执行该查询的hakish方式。这里有关于动态SQL的更多阅读:http://www.sommarskog.se/dynamic_sql.html

我现在在家里,无法访问SQL Server。如果需要的话,我会在早上编辑我的帖子。