【问题标题】:Temp tables on the current connection当前连接上的临时表
【发布时间】:2012-07-23 02:20:17
【问题描述】:

如果我这样做:

select * from tempdb.sys.tables

我将看到系统中的所有临时表,但是该视图没有关于每个表属于哪个连接/用户的信息。我有兴趣只查找我在当前连接上创建的表。有没有办法做到这一点?

谢谢-e

附言是的,我可以尝试阅读列出的每个表,并认为那些成功的表应该是我的(在最近的版本中,一个人无法读取其他连接的表),但这种方法成本太高,因为可能有数千个表系统

p.p.s.我确实读过Is there a way to get a list of all current temporary tables in SQL Server?,它提出了正确的问题,但没有得到好的答案

【问题讨论】:

  • 如果您是在自己的连接上自己创建的表,那么为什么不跟踪您自己创建的表呢?
  • @RobertHarvey - 你总是那么务实,来吧 - 这是一个有趣的问题。
  • @RobertHarvey - 因为我不能保证我是唯一一个创建表的人,例如我调用的代码(并且我可能无权访问)可能会创建我不知道的表

标签: sql sql-server temp-tables


【解决方案1】:

假设您没有使用三个连续的下划线命名您的#temp 表,那么这应该只选择您的#temp 表。但是,它不会提取您的表变量,您也不能以某种方式更改此代码以选择其他人连接上的表 - 这仅适用于 OBJECT_ID('tempdb..#foo') 只能为您会话中的表返回 true。

SELECT 
  name = SUBSTRING(t.name, 1, CHARINDEX('___', t.name)-1),
  t.[object_id]
FROM tempdb.sys.tables AS t
WHERE t.name LIKE '#%[_][_][_]%'
AND t.[object_id] = 
  OBJECT_ID('tempdb..' + SUBSTRING(t.name, 1, CHARINDEX('___', t.name)-1));

您可能还对这些表中的每一个使用的空间感兴趣(至少对于堆或聚集索引而言),例如:

SELECT 
    name = SUBSTRING(t.name, 1, CHARINDEX('___', t.name)-1),
    t.[object_id], 
    p.used_page_count, 
    p.row_count
FROM tempdb.sys.tables AS t
INNER JOIN tempdb.sys.dm_db_partition_stats AS p
ON t.[object_id] = p.[object_id]
WHERE t.name LIKE '#%[_][_][_]%'
AND p.index_id IN (0,1)
AND t.[object_id] = 
    OBJECT_ID('tempdb..' + SUBSTRING(t.name, 1, CHARINDEX('___', t.name)-1));

您可以扩展它以显示所有索引的总空间。因为这些是#temp 表,所以我没有费心汇总每个分区。

【讨论】:

  • @Hogan 因为OBJECT_ID('tempdb..#foo') 只会在 创建了一个名为#foo 的#temp 表时返回非空值。如果您在不同的窗口中创建该表,OBJECT_ID 将无法解决它。我不是 100% 清楚 SQL Server 如何跟踪哪个#temp 表属于哪个会话,因为该信息当然没有公开,但它确实保持跟踪。
  • 谢谢,根据我的测试,如果这是您所依赖的,我只是要发布。
  • @AaronBertrand - 这是一个聪明的解决方案,但我来问是因为我对名称不包含 3 个下划线的要求不满意,这是无法保证的。我还看到了名为 #29AFBDD0 的临时表(尽管我不太确定这些临时表是如何存在的),这将重做逻辑。老实说,我不敢相信没有去杂化功能!类似select object_name_base(name) from tempdb.sys.tables)
  • @ekkis 顺便说一句,我同意你的看法,应该有一种方法可以将临时表映射到会话。请在这里投票和评论:connect.microsoft.com/SQLServer/feedback/details/285110/… 哦,这里也是:connect.microsoft.com/SQLServer/feedback/details/285113/…
  • @AaronBertrand - 我带头向 M$ 提出了建议。您可以通过以下方式为我投票:goo.gl/JRS7m
【解决方案2】:
select * 
from tempdb.sys.objects
where object_id('tempdb.dbo.' + name, 'U') is not null 
  AND name LIKE '#%'

会告诉你 tempdb 中所有可以访问的以 # 开头的表,但是 Aaron 的脚本让我大吃一惊,哈哈

【讨论】:

  • 确实!他的解决方案非常聪明
  • 我仍在努力获得一个赞成票,这样我就可以评论其他人的问题了,哈哈
  • @Aushin 这个查询实际上返回了我的#temp 表和 tempdb 中的所有永久表(显然其中一些可能属于我,但不是全部)。
  • @AaronBertrand 我想我的意思是“如果你有适当的权限,你可以访问 tempdb 中的所有表”。
  • 这个问题专门针对临时表。
【解决方案3】:

要找出创建对象的用户的名称,您只需检查架构 ID 并与 Schemas 表交叉引用

Select sch.name as 'User Owner' from tempdb.sys.tables TBL
join tempdb.sys.schemas SCH on TBL.schema_id = SCH.schema_id
where TBL.name like '#tmp_Foo%'

【讨论】:

    猜你喜欢
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多