sql - 根据 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, 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,如下所示:
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 建议的添加模式。
推荐阅读
- javascript - 无法使日期时间选择器的默认值正常工作
- oracle - 在其他模式中重命名 Oracle 表
- c# - 托管在 IIS 上的 Blazor WebAssembly - 只有 API 有效
- javascript - 如何在javascript中的onclick内部建立索引
- docker - Portainer Stack - docker compose 问题与 MacVLan 网络
- networking - 视频流,它是如何工作的?
- android - React Native - 遇到两个孩子使用相同的键,`221`
- javascript - bootstrap - 如何默认显示模式而不是使用按钮
- java - 谷歌云功能集成测试与Spring Boot中的配置文件?
- javascript - 不同语言的按键的KeyCode/Char?