【问题标题】:Connection scoped temp tables across stored procedures跨存储过程的连接范围临时表
【发布时间】:2013-01-23 04:10:11
【问题描述】:

我正在研究数据虚拟化解决方案。用户可以编写自己的 SQL 查询作为我所做查询的过滤器。我不想每次从数据库中选择一些东西时都运行这个过滤器查询(它可能是一系列复杂的连接)。

我的想法是在脚本级别使用 # 临时表并保持连接处于活动状态。然后将从中选择此#temp 表,但仅在用户更改过滤器时才更新。我的想法是我实际上可以从存储过程中使用它,并且表的范围仅限于该连接。

我从建议使用动态 sql 和 ## 以连接进程 ID 命名的全局临时表的人那里得到这个想法,以便使每个连接都有一个唯一的全局临时表。这是为了克服跨存储过程共享临时表的问题。不过好像有点笨拙。

我用下面的代码做了一个快速测试,似乎工作正常

-- Run script at connection open from some app
SELECT * INTO #test
FROM   dataTable

-- Now we can use stored procedures with #test table
EXECUTE selectFromTempTable

EXECUTE updateTempTable @sqlFilterString

EXECUTE selectFromTempTable

我能看到的唯一真正问题是连接必须保持活动状态,持续时间可能是几个小时。一个用户可以同时运行多个连接。单个数据库服务器上的用户数最多为 20。 如果它是一个大问题,我可以做到这一点,以便应用程序可以根据需要关闭和打开它们,这样每个用户一次只能打开 1 个连接。甚至可能在不使用时将其关闭,并在需要时重新打开,而延迟必须等待查询运行。

这是不好的做法吗?或因不运行过滤器查询而扼杀任何性能优势?这是在 SQL Server 2008 及更高版本上。

【问题讨论】:

  • 您不必将初始查询的结果保存在应用程序的内存中,用户可以继续过滤吗?
  • 我可能会,但这取决于过滤器查询返回的结果的大小。老实说,你的权利,但你知道“业主不愿意承诺任何限制”,所以我必须建造它,以便它可以煮咖啡和发送电子邮件。

标签: sql-server tsql stored-procedures database-connection temp-tables


【解决方案1】:

我想我会创建一个永久表,使用 spid(进程 ID)作为键值。每个连接都有自己的进程 ID,因此任何人都可以使用它来识别表中的条目:

create table filter( 
  spid int, 
  filternum int, 
  filterstring varchar(255), 
  <other cols> );
create unique index filterindx on filter(spid, filternum);

那么当用户创建过滤条目时:

delete from filter where spid = @@spid
insert into filter(spid, filternum, filterstring) select @@spid, 1, 'some sql thing'
insert into filter(spid, filternum, filterstring) select @@spid, 2, 'some other sql thing'

然后您可以通过选择where spid = @@spid 等来访问每个用户的过滤器值

【讨论】:

    猜你喜欢
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 2011-09-29
    相关资源
    最近更新 更多