根据 sys.tables 中的名称声明一个变量,然后在动态 SQL 中根据该变量删除表

Posted

技术标签:

【中文标题】根据 sys.tables 中的名称声明一个变量,然后在动态 SQL 中根据该变量删除表【英文标题】:Declare a variable based on name in sys.tables then delete the table based on that variable in dynamic SQL 【发布时间】:2020-11-30 13:41:00 【问题描述】:

所以我希望第一段代码找到表名,然后如果该表名存在并且超过 3 天,则删除该表。

我对这段代码的问题是代码没有用实际的表 DrinkSales 替换 @temp_name。所以变量没有在 select 语句中正确设置。

当前代码:

declare @table varchar(100)  = 'DrinkSales' 
DECLARE @temp_name VARCHAR(100)
declare @drop varchar(max) = '

DECLARE @temp_name VARCHAR(100)

select @temp_name= name 
FROM sys.objects
WHERE   DATEDIFF(day, create_date, getdate()) > 3
and name = '''+@table+'''

select @temp_name
                     --if object_id(''dbo.'+@table+''', ''U'') is not null -- needs to be changed to detect if variable is null rather than table.
                     --drop table dbo.'+@table+'

                     '

print(@drop) 
exec(@drop)

所以结果应该是:

DECLARE @temp_name VARCHAR(100)

select @temp_name= name 
FROM sys.objects
WHERE   DATEDIFF(day, create_date, getdate()) > 3
and name = 'DrinkSales'

select @temp_name
                     --if object_id('dbo.DrinkSales', 'U') is not null -- this should be changed to  
                     --drop table dbo.DrinkSales
                      *if @temp_name is not null *
                        *drop dbo.drinksales*



                     

(1 row affected)

【问题讨论】:

您已经标记了动态 sql - 您需要使用它。您不能将对象名称存储在标量变量中并使用它来引用表(或列等)。当您的“名称”匹配实际上不是表的对象时,您认为会发生什么?不要假设 - 仅针对表正确过滤查询。您已经有一个涉及动态 sql 的问题 - 只需在此处应用该概念即可。 【参考方案1】:

我认为您过度引用 - 动态 SQL 中的常见问题。

您可以(并且应该)最小化所需的动态 SQL,如下所示:

declare @schema varchar(100) = 'dbo', @table varchar(100)  = 'Proposal', @temp_name varchar(100);

if exists (
  select 1
  from sys.objects
  where datediff(day, create_date, getdate()) > 3
  and [name] = @table
  and [schema_id] = schema_id(@schema)
)
begin
  declare @drop varchar(max) = 'drop table ' + quotename(@schema) + '.' + quotename(@table) + ';';
  print(@drop) 
  --exec(@drop)
end;

使用quotename 来防止SQL 注入很重要。

还要注意 @David Browne 建议的添加架构。

【讨论】:

应该在两个查询中指定架构。

以上是关于根据 sys.tables 中的名称声明一个变量,然后在动态 SQL 中根据该变量删除表的主要内容,如果未能解决你的问题,请参考以下文章

go变量

根据 SQL 管理器中的 IF 语句设置变量

Scala之变量

go语言基本语法:变量的声明

哪个数据库在 SQL Server 中存储 sys.tables 或 sys.indexes?

JavaScript的变量