如何从一个表中选择table_name值并根据条件从table_name表中删除记录?

时间:2018-05-15 15:00:29

标签: sql sql-server dynamic parameter-passing

我们有一张桌子。让我们称之为Table_A。 Table_A包含一堆table_names和与每个table_name关联的数值。请参考下图

Example

有人可以帮我写一个查询: 从TABLE_A逐个选择table_names;转到该表,检查Table_A中NO_OF_DAYS的每条记录的Date_inserted,如果记录比Table_A中的NO_OF_DAYS旧,则从该特定表中删除该记录。

我猜我们必须为此查询创建动态值,但我很难过。

因此,在上图中,查询应该:

  1. 从Table_A
  2. 中选择第一个table_name(T_Table1)
  3. 转到该表(T_Table1)
  4. 根据条件
  5. 检查(T_Table1)中每条记录的插入日期
  6. 如果条件(IF记录在NO_OF_DAYS之前插入,在这种情况下是90,那么删除记录; ELSE移到下一个 记录)
  7. 转到Table_A
  8. 中的下一个表(T_Table2)
  9. 继续,直到Table_A中的所有table_names都已执行

1 个答案:

答案 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