我们有一个遗留应用程序,它使用以下命名约定创建了多个表:table_20140618,table_20140623等,其中日期是程序运行的时间。我现在正在尝试清理数据库,并删除其中的一些表。
在每个表中有两个字段:DateStarted和DateFinished。我想选择表(然后删除它们),其中DateStarted有值,而DateFinished是非null。
目前我正在使用以下查询来选择以'table_'开头的所有表 如:
Select (TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME LIKE 'table_%';
我不确定如何通过在他们的字段中搜索来将所有表格放在一起。我可以通过代码完成它,但这应该意味着数据库上有多次点击。有什么想法吗?
答案 0 :(得分:1)
在我上面的第一条评论之后做了这个,但你应该能够改变代码以适合你的规格。基本上,这将使用动态SQL根据您的过滤器和条件生成命令。因此,您可以在 SELECT @SQL = ... 部分中使用您想要的任何条件来检查日期,然后在满足条件时添加表名。
该脚本返回一个包含表名和drop命令的列表,因此您可以在执行此操作之前检查自己正在执行的操作。但是从那里你可以复制drop命令列表并在需要时执行它。
IF OBJECT_ID('tempdb..#TABLES') IS NOT NULL
DROP TABLE #TABLES
CREATE TABLE #TABLES (ROWNMBER INT IDENTITY(1,1), TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT)
/*
-- Old code to fetch ALL tables with specified name
INSERT INTO #TABLES
SELECT name
FROM sys.tables
WHERE name LIKE 'table[_]%'
*/
-- Updated code to fetch only those tables which contain the DateStarted and DateFinished columns
INSERT INTO #TABLES
SELECT TAB.name
FROM sys.tables TAB
LEFT JOIN sys.columns C1 on C1.object_id = TAB.object_id
AND C1.name = 'DateStarted'
LEFT JOIN sys.columns C2 on C2.object_id = TAB.object_id
AND C2.name = 'DateFinished'
WHERE TAB.name LIKE 'table[_]%'
AND C1.name IS NOT NULL AND C2.name IS NOT NULL
IF OBJECT_ID('tempdb..#DROPPABLE_TABLES') IS NOT NULL
DROP TABLE #DROPPABLE_TABLES
CREATE TABLE #DROPPABLE_TABLES (TABLENAME VARCHAR(256) COLLATE DATABASE_DEFAULT)
DECLARE @ROW_NOW INT, @ROW_MAX INT, @SQL VARCHAR(MAX), @TABLENAME VARCHAR(256)
SELECT @ROW_NOW = MIN(ROWNMBER), @ROW_MAX = MAX(ROWNMBER) FROM #TABLES
WHILE @ROW_NOW <= @ROW_MAX
BEGIN
SELECT @TABLENAME = TABLENAME FROM #TABLES WHERE ROWNMBER = @ROW_NOW
SELECT @SQL =
'IF (SELECT COUNT(*) FROM '+@TABLENAME+' WHERE DateStarted IS NOT NULL) > 0
AND (SELECT COUNT(*) FROM '+@TABLENAME+' WHERE DateFinished IS NOT NULL) > 0
SELECT '''+@TABLENAME+''''
INSERT INTO #DROPPABLE_TABLES
EXEC(@SQL)
SET @ROW_NOW = @ROW_NOW+1
END
SELECT *, 'DROP TABLE '+TABLENAME DROPCOMMAND FROM #DROPPABLE_TABLES
修改强> 根据你的评论,似乎并非所有这些表都有这些列。您可以使用以下脚本来标识所述表以及缺少哪个列,以便您可以进一步检查它们。您可以使用相同的想法来过滤第一个查询的结果,只计算具有这些列的表。
SELECT TAB.name TABLENAME
, CASE WHEN C1.name IS NULL THEN 'Missing' ELSE '' END DateStarted_COL
, CASE WHEN C2.name IS NULL THEN 'Missing' ELSE '' END DateFinished_COL
FROM sys.tables TAB
LEFT JOIN sys.columns C1 on C1.object_id = TAB.object_id
AND C1.name = 'DateStarted'
LEFT JOIN sys.columns C2 on C2.object_id = TAB.object_id
AND C2.name = 'DateFinished'
WHERE TAB.name LIKE 'table[_]%'
AND (C1.name IS NULL
OR C2.name IS NULL)