Mrp*_*hin 5 sql t-sql sql-server dynamic-sql
我支持第三方软件包的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
Run Code Online (Sandbox Code Playgroud)
当您提前不知道表名时,我不知道如何摆脱动态 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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5947 次 |
| 最近记录: |