查询多个用户 - 最佳实践

时间:2013-02-27 22:40:12

标签: sql tsql sql-server-2008-r2

我目前有大约10个用户在我的工作场所使用他们自己的个性化查询进行内部流程。用户在查询顶部输入一些值,点击执行,然后他们的报告显示在网格中。它们访问的源数据表是相同的,但其中创建的表是使用后缀_User1,_User2 ... User10进行个性化的。每次运行查询时,都会删除先前创建的表并再次创建。整个查询大约需要1秒钟才能运行。

对于5个步骤来说,大部分结构看起来重复了5次以达到他们想要的输出:

DROP TABLE z
SELECT *
INTO z
FROM y

现在,用户数量乘以50,这意味着主查询代码中的每个调整都将导致我更改50个特定于用户的查询并将其发送回去。 10个用户可管理和烦人,完全无法管理50个。

我的问题是,构建数据库/查询的最佳方法是什么?理想情况下,我想只有一个查询,一组创建的表(不是50)。由于运行只需1秒钟,我们是否会冒两个或更多用户(使用不同输入)同时运行查询的风险,访问相同的表并以某种方式获取错误的数据,因为他们在同一时间运行它?

通常情况下是否存在特定的方式?希望有人可以解释一下。

由于

1 个答案:

答案 0 :(得分:2)

免责声明:正如我在评论中指出的那样,让一群用户直接访问SSMS来运行报告是一个非常糟糕的主意。获得某种前端,甚至是简单的MS Access数据库 - 您只需要一个许可证来开发数据库,​​例如,您可以为其余用户提供Access Runtime。如果用户不知道他们在做什么,有很多方法可以让你真正搞砸。我将在下面提供一些想法,但我不建议这样做


一种解决方案:使用临时表,这样您就不必担心每个用户的表重叠:

-- drop the table if it already exists
if object_id('tempdb..#z') is not null
    DROP TABLE #z

SELECT *
INTO #z
FROM y

当您使用#为表名添加前缀时,它将成为连接范围的临时表,这意味着即使它们具有相同的名称,单独的会话也不会在其他会话中看到临时表。


除非你有一些非常复杂的场景,否则通常不需要创建临时表。您应该能够使用子查询,视图,CTE和存储过程来实时生成输出,而不涉及任何新表。您甚至可以构建引用其他视图的视图和过程,以便组织复杂的逻辑。例如,您可以将逻辑封装到存储过程中,如下所示:

CREATE PROCEDURE TheReport
(
    @ReportID int,
    @Name varchar(50),
    @SomeField varchar(10)
)
AS
BEGIN
    -- do some complicated query here
    SELECT field1, field2 FROM Result Q
END

然后您甚至不必向用户发送更新(除非字段更改)。只需让他们的查询调用存储过程,您就可以在方便时直接更新过程:

DECLARE @ReportID int
DECLARE @Name varchar(50)
DECLARE @SomeField varchar(10)

-- YOU CAN MODIFY THIS --
SET @ReportID = 5
SET @Name = 'MyName'
SET @SomeField = 'abc'
-- DON'T MODIFY BELOW THIS LINE --

EXEC [TheReport] @ReportID, @Name, @SomeField;