我支持第三方软件包的 SQL 数据库。他们有很多所谓的“影子表”,实际上只是审计表。这一切都很好,但他们的系统不会清理这些表,所以这取决于我。他们还在每次升级时添加新的“影子表”,恕不另行通知。我们清除表的旧方法是使用一长串 DELETE FROM
语句,但这个列表已经变得非常长并且难以维护。
为了尝试使清除过程更易于维护并自动捕获新的“影子表”,我编写了以下存储过程。存储过程有效,但我更愿意找出一种不使用游标和动态查询的方法,因为这将每天在许多不同的表上运行。是否有其他方法可以在不使用游标和动态查询的情况下执行此操作?
DECLARE @workingTable varchar(128);
DECLARE @sqlText varchar(250);
DECLARE @CheckDate DATETIME = DATEADD(yy, -2, GETDATE());
DECLARE curKey SCROLL CURSOR FOR
SELECT name AS TableName
FROM dataTEST.sys.tables
WHERE (name like '%[_]h' OR name like '%[_]dh')
ORDER BY name
OPEN curKey
WHILE @@fetch_status = 0
BEGIN
FETCH NEXT FROM curKey INTO @workingTable
SET @sqlText = 'DELETE FROM DataTEST.dbo.' + @workingTable + ' WHERE LAST_MOD < ''' + CONVERT(CHAR(10), @CheckDate, 101) + ''';'
--PRINT @sqlText
EXEC (@sqlText)
END
CLOSE curKey
DEALLOCATE curKey
最佳答案
当您提前不知道表名时,我不知道如何摆脱动态 SQL。 SQL Server 有一项功能,您可以在 select
语句中对返回的每一行进行一次变量赋值。这可以用来消除游标并将包含所有delete
语句的一个字符串传递给SQL Server来执行
DECLARE @sqlText nvarchar(MAX) = ''; -- initialize because NULL + 'x' is NULL
DECLARE @CheckDate DATETIME = DATEADD(YEAR, -2, GETDATE());
SELECT @sqlText = @SqlText + 'DELETE FROM dataTEST.dbo.' + QUOTENAME(name)
+ ' WHERE LAST_MOD < @CheckDate ; '
FROM dataTEST.sys.tables
WHERE (name like '%[_]h' OR name like '%[_]dh')
ORDER BY name
IF @@ROWCOUNT > 0
EXEC sp_executesql @sqlText
, N'@CheckDate DATETIME'
, @CheckDate
关于sql - 在没有动态 SQL 的情况下对多个表运行相同的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32210193/