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

问题描述

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

此代码的问题是该代码未将@temp_name替换为实际的表DrinkSales。因此,该变量未在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,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最小化,如下所示:

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建议的架构的添加。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...