我们有一张桌子。让我们称之为Table_A。 Table_A包含一堆table_names和与每个table_name关联的数值。请参考下图
有人可以帮我写一个查询: 从TABLE_A逐个选择table_names;转到该表,检查Table_A中NO_OF_DAYS的每条记录的Date_inserted,如果记录比Table_A中的NO_OF_DAYS旧,则从该特定表中删除该记录。
我猜我们必须为此查询创建动态值,但我很难过。
因此,在上图中,查询应该:
答案 0 :(得分:0)
您在尝试时(在评论中)发布的内容,根本就不起作用。让我们先实际格式化,我们应该:
SET SQL = '
DELETE [' + dbo + '].[' + TABLE_NAME + ']
where [Date_inserted ] < '
SET SQL = SQL + ' convert(varchar, DATEADD(day, ' + CONVERT(VARCHAR, NO_OF_DAYS) + ',' + '''' + CONVERT(VARCHAR, GETDATE(), 102) + '''' + '))'
PRINT SQL
EXEC (SQL)
首先,我实际上不知道你甚至想在这里做什么。您有[' + dbo + ']
之类的内容,这意味着您引用了列dbo
;当您使用SET
时,则不存在任何列dbo
。此外,变量在SQL Server中以@
为前缀;你没有。
无论如何,解决方案。有些人可能不喜欢这个,因为我使用的是CURSOR
,而不是一次性完成。但是,我确实有我的理由。 CURSOR
实际上不是&#34;坏&#34;像许多人相信的那样;问题是人们经常不正确地使用它们。例如,使用CURSOR
循环记录并创建层次结构是一个可怕的想法;有更好的数据集方法。
那么,我的理由是什么?首先,我可以参数化动态SQL;这在CURSOR
之外会更难,因为我需要为每个DELETE
声明一个不同的参数。另外,使用CURSOR
,如果DELETE
在一张桌子上失败,则其他人不会;一段长的动态SQL意味着如果其中一个事务失败,它们都将被回滚。此外,根据删除的大小,这可能是一个非常大的DELETE
。
重要的是,你了解我在这里所做的事情;如果你不认为这对自己来说是一个问题。如果您将来需要麻烦拍摄,会发生什么?所以不是这样的支持网站;你需要支持自己的代码。如果你不能理解你所使用的代码,或者不知道它先做了什么(或者你做错了什么)。
注意我在没有耗材样本数据的情况下使用自己的对象:
CREATE TABLE TableOfTables (TableName sysname,
NoOfDays int);
GO
INSERT INTO TableOfTables
VALUES ('T1',10),
('T2',15),
('T3',5);
GO
DECLARE Deletes CURSOR FOR
SELECT TableName, NoOfDays
FROM TableOfTables;
DECLARE @SQL nvarchar(MAX), @TableName sysname, @Days int;
OPEN Deletes;
FETCH NEXT FROM Deletes
INTO @TableName, @Days;
WHILE @@FETCH_STATUS = 0 BEGIN
SET @SQL = N'DELETE FROM ' + QUOTENAME(@TableName) + NCHAR(10) +
N'WHERE DATEDIFF(DAY, InsertedDate, GETDATE()) >= @dDays;'
PRINT @SQL; --Say hello to your best friend. o/
--EXEC sp_executeSQL @SQL, N'@dDays int', @dDays = @Days; --Uncomment to run
FETCH NEXT FROM Deletes
INTO @TableName, @Days;
END
CLOSE Deletes;
DEALLOCATE Deletes;
GO
DROP TABLE TableOfTables;
GO