【问题标题】:Dynamically reference tables without using dynamic SQL不使用动态 SQL 动态引用表
【发布时间】:2010-11-26 16:36:19
【问题描述】:

在 SQL Server 2008 中,我有一个执行复杂查询的存储过程。我会将结果写入临时表(不是系统临时表,而是手动管理的)。

表的名称是用户的网络会话 ID 的字符串表示形式。这解决了并发问题。这将传递给将创建表的存储过程。为了清理,该名称将与时间戳一起记录在维护表中。

然而,这个名字显然是动态的。我不想使用动态 SQL,因为这会排除复杂查询的任何编译。我知道这是在推动事情,但我想做的是如下:

DECLARE @TableName varchar(100)
SET @TableName = CAST(@SessionID AS varchar)

INSERT INTO @TableName
SELECT....{complex query}

我该怎么做?

更多信息:

记录集可能有数万行(仅限 ID)。用户可以对这个记录集应用进一步的过滤,从而减少它。因此它必须是服务器上的一个表。

【问题讨论】:

    标签: sql-server stored-procedures dynamic-sql


    【解决方案1】:

    您为什么不创建一个选择的临时表,而是将会话 ID 作为字段包含在内,这将使记录变得唯一?

    【讨论】:

    • 结合我昨天尝试的一个小技巧,这是个好主意。创建 1 个临时表,其中 (SessionID, UID) 作为 PK & RID 作为 Col3,UID 是 IDENTITY(1,1) [这是诀窍]。从性能的角度来看,您的想法将与专用表相当,甚至比专用表更快,并且使维护和访问变得简单。我喜欢它。
    【解决方案2】:

    您可以先将复杂的查询插入到#temp 表中,然后使用动态sql 将其插入到以sessionID 命名的表中。

    select ...
    into #temp 
    ....{complex query} 
    
    set @sql = 'select * into ' + @tablename + ' from #temp' 
    exec (@sql)
    

    【讨论】:

    • 这是一个想法。即使我使用内存中的临时表@temp,它仍然可以处理数万条记录,对服务器没有重大影响,并且由于“双写”而没有特别的速度损失。不错!
    【解决方案3】:

    它如何使用在编译时不知道的表来编译查询?据我所知,你想做的事情是不可能的。

    您为什么不寻找其他解决方案,例如将结果存储在以会话 ID 为键的表中的 XML 字段中,每个用户/会话/结果集一行?

    您也可以将数据拉回 .NET 并将其直接存储在 Session 中。取决于您使用的会话提供程序的效果如何。

    您还可以将结果存储在临时文件中,并使用时间戳在单个表中跟踪文件,并每隔一段时间运行批处理作业以清除旧会话或非活动会话中的文件。

    添加,基于“更多信息”:

    好的。是时候打“过早优化”牌了。 :)

    您是否有一个已经太慢的现有解决方案?您是否已经研究过如何在不缓存大型结果集的情况下对其进行简化?

    假设您有:您希望拥有多少用户/会话?这些 ID 被隔离和缓存后将如何使用?它们听起来像是进一步查询所需要的,这意味着它们的最佳位置是在具有静态名称的表中。

    此时我的建议是:将所有结果存储在一个关联表中,如create table tempResults(session_id guid, other_id int)。然后,您可以将此表的连接硬编码到其他查询中。

    【讨论】:

    • “SELECT FROM”是固定部分,因此可以编译。只有“INSERT INTO”是动态的。从字面上看,QUERY 是固定的,它只是 what 我将结果写入更改中。记录集可能有数万行,因此不适合会话变量。临时文件是一个想法!
    • 啊,临时文件的问题是用户可以应用过滤来减少记录集。所以它必须是服务器上的一个表。
    • 这是一个新项目,所以数据库是全新的。我认为您对固定表的看法是正确的。我已经研究了简化它的方法。缓存大型结果集是用户要求。似乎以下方法可以解决问题: CREATE TABLE [dbo].[UserMentionsDataset] ( [ClientID] [int] NOT NULL, [UID] [int] IDENTITY(1,1) NOT NULL, [MentionID] [int] NOT NULL,约束 [PK_UserMentionsDataset] 主键集群([ClientID] ASC,[UID] ASC)
    猜你喜欢
    • 2011-03-03
    • 1970-01-01
    • 2018-10-24
    • 2013-10-14
    • 2016-07-21
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多