当我只知道部分名称时检查是不是存在临时表?

Posted

技术标签:

【中文标题】当我只知道部分名称时检查是不是存在临时表?【英文标题】:Check if a temp table exists when I only know part of the name?当我只知道部分名称时检查是否存在临时表? 【发布时间】:2020-09-15 21:09:37 【问题描述】:

我有一个函数来检查我的数据库中是否存在某些表,使用表名的一部分作为匹配键(我的表命名约定包括唯一的表名前缀)。它使用如下 select 语句,其中@TablePrefix 是函数的参数,包含表名的前几个字符:

DECLARE @R bit;

    SELECT @R = COUNT(X.X)
        FROM ( 
          SELECT TOP(1) 1 X FROM sys.tables WHERE [name] LIKE @TablePrefix + '%' 
        ) AS X;
    
RETURN @R;

我的问题是,我怎样才能扩展此功能以也适用于#temp 表?

我尝试检查名称的第一个字符是否为#,然后使用相同的逻辑从tempdb.sys.tables 中进行选择,但这似乎有一个致命的缺陷——当存在任何具有匹配名称的临时表时,它会返回一个肯定的结果,即使不是由当前会话创建的 - 即使是由不同数据库中的 SP 创建的。似乎没有任何直接的方法可以将选择范围缩小到仅存在于当前会话上下文中的那些临时表。

我不能使用似乎普遍建议用于检查临时表的其他方法 - IF OBJECT('tempdb..#temp1') IS NOT NULL - 因为这需要我知道表的全名,而不仅仅是前缀。

【问题讨论】:

您肯定知道更多nothing 的对象名称....否则,即使您确实找到了对象,您也不知道您在寻找什么。这感觉就像XY Problem 谢谢@Larnu - 好吧,上述问题反映了应用程序当前工作方式的一部分。我只需要知道可能存在的一组表中是否存在任何一个临时表,这些表都以与名称的一部分相同的前缀开头 - 例如[name] LIKE '#DNA_%' 。当然还有其他可能更好的方法来解决这个问题,但它们需要我重新编码应用程序的某些部分,而我希望避免这种情况。无论如何,也许这是我现在应该抓住的荨麻! 【参考方案1】:
create table #abc(id bit);
create table #abc_(id bit);
create table #def__(id bit);
create table #xyz___________(id bit);
go

select distinct (left(t.name, n.r)) as tblname
from tempdb.sys.tables as t with(nolock)
cross join  (select top(116) row_number() over(order by(select null)) as r from sys.all_objects with(nolock)) as n
where t.name like '#%'
and object_id('tempdb..'+left(t.name, n.r)) is not null;


drop table #abc;
drop table #abc_;
drop table #def__;
drop table #xyz___________;

【讨论】:

谢谢@lptr 我已经使用这种方法作为我的解决方案的基础,只需将 object_id 的检查添加到 tempdb.sys.tables 中的选择中。另外,我只需要知道是否存在任何一张表,我已将选择限制为 TOP(1)。【参考方案2】:

试试这样的:

DECLARE @TablePrefix VARCHAR(50) = '#temp';

    DECLARE @R BIT, @pre VARCHAR(50) = @TablePrefix + '%';

    SELECT @R = CASE LEFT ( @pre, 1 )
        WHEN '#' THEN ( 
            SELECT CASE WHEN EXISTS ( SELECT * FROM tempdb.sys.tables WHERE [name] LIKE @pre ) THEN 1
            ELSE 0
        END )
        ELSE ( 
            SELECT CASE WHEN EXISTS ( SELECT * FROM sys.tables WHERE [name] LIKE @pre ) THEN 1
            ELSE 0
        END )
    END;
    
    SELECT @R AS TableExists;

【讨论】:

感谢您的建议,但问题是如果存在由其他进程创建的具有匹配名称的临时表,这将返回误报 - 与我的应用程序无关。这就是我最初遇到的问题。

以上是关于当我只知道部分名称时检查是不是存在临时表?的主要内容,如果未能解决你的问题,请参考以下文章

调试时获取临时表数据

如何判断一个临时表是不是存在呢?

Informix - 如果存在则删除临时表

临时表在哪里存储在 sql server 中?

检查临时表是否存在

如果多个存储过程正在创建具有相同名称的临时表,我如何知道要删除哪个临时表?