1

我在一个数据库中工作,每个用户在他们的架构中都有一个名为 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 
4

2 回答 2

0

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

SELECT cols FROM MyDatabase..FindResults;

(省略模式名称。)

然而,这似乎很容易出错,恕我直言,您应该有单独的、模式绑定的存储过程,或者有一个带有列的表来指示它是谁的行。

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

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

但是我还没有机会对此进行测试(无论如何,您都更有能力在您的场景中进行测试)。

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

于 2013-03-29T21:49:59.027 回答
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

这也是进行该查询的一种狂妄自大的方式。更多关于动态 SQL 的阅读:http: //www.sommarskog.se/dynamic_sql.html

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

于 2013-10-09T17:37:31.283 回答