问题描述
所以我期望第一段代码找到该表名,然后如果该表名存在并且已存在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建议的架构的添加。