Tsql 需要帮助创建存储过程来迭代数据库中的表,然后在每个表上运行SQL语句吗

Tsql 需要帮助创建存储过程来迭代数据库中的表,然后在每个表上运行SQL语句吗,tsql,stored-procedures,sql-server-2008-r2,Tsql,Stored Procedures,Sql Server 2008 R2,我们的应用程序不会删除数据,因为我们会将数据保留一段时间,相反,在数据库中存储数据的大多数表中都有一个列删除位,删除时我们将其标记为1,否则默认值为0 我想创建一个存储过程,它迭代数据库中的所有表,检查是否存在名为deleted的列,如果存在,则对LastUpdatedUtc列datetime2进行检查,如果日期超过6个月且deleted=1,则删除该行 这个应用程序正在持续开发中,因此可以添加表,这就是为什么我想创建一个脚本来迭代表,而不是为每个表添加一行,并记住在添加新表时添加它们 SQLS

我们的应用程序不会删除数据,因为我们会将数据保留一段时间,相反,在数据库中存储数据的大多数表中都有一个列删除位,删除时我们将其标记为1,否则默认值为0

我想创建一个存储过程,它迭代数据库中的所有表,检查是否存在名为deleted的列,如果存在,则对LastUpdatedUtc列datetime2进行检查,如果日期超过6个月且deleted=1,则删除该行

这个应用程序正在持续开发中,因此可以添加表,这就是为什么我想创建一个脚本来迭代表,而不是为每个表添加一行,并记住在添加新表时添加它们

SQLServer2008R2存储过程中对此的任何帮助都将是巨大的帮助

多谢各位

编辑谢谢你奥马尔这是我到目前为止的想法。如果有人知道更好的方法,请告诉我

IF OBJECT_ID('tempdb..#tmpTables') IS NOT NULL DROP TABLE #tmpTables
GO

CREATE TABLE #tmpTables
(
ID INT,
TableName NVARCHAR(100) NOT NULL
)
GO

SET NOCOUNT ON
GO

INSERT #tmpTables
SELECT [object_id], [name] FROM sys.all_objects WHERE type_desc = 'USER_TABLE' ORDER BY [name]

DECLARE @TN NVARCHAR(100)
DECLARE @SQL NVARCHAR(max)
DECLARE @PurgeDate VARCHAR(50)

SET @PurgeDate = DATEADD(MONTH, -6, GETUTCDATE())

WHILE (SELECT COUNT(*) FROM #tmpTables) > 0
BEGIN
    SELECT TOP 1 @TN = TableName FROM #tmpTables
    IF EXISTS(SELECT * FROM sys.columns WHERE name = 'deleted' AND OBJECT_ID = OBJECT_ID(@TN)) 
    BEGIN
        IF EXISTS(SELECT * FROM sys.columns WHERE name = 'LastUpdatedUtc' AND OBJECT_ID = OBJECT_ID(@TN))  
        BEGIN
            SET @SQL = 'SELECT Count(*) As Counter FROM ' + @TN + ' WHERE [deleted] = 1 AND [LastUpdatedUtc] < ''' + @PurgeDate + '''' -- this will be the delete line when the code is final, just outputting results for now
            EXEC(@SQL)
        END      
     END
    DELETE #tmpTables WHERE TableName=@TN
END

DROP TABLE #tmpTables

这是我的第一次尝试,没有经过测试,因此可能会有一些打字错误/语法错误,但这应该让您开始:

    declare @date6MonthsBack varchar(50)
    select @date6MonthsBack = dateadd(month, -6, getdate());

    declare c cursor for
        select 'delete from ' + quotename(name) + ' where [deleted] = 1 and [LastUpdatedUtc] <= ''' + @date6MonthsBack + '''' from sys.tables
        where object_id in (select object_id from sys.columns where name = 'deleted')
        and object_id in (select object_id from sys.columns where name = 'LastUpdatedUtc')

    declare @sql varchar(max)
    open c; fetch next from c into @sql
    while (@@fetch_status = 0) begin
        print(@sql)
        --exec(@sql) --uncomment this line to do the actual deleting once you have verified the commands.
    fetch next from c into @sql; end
    close c; deallocate c

您可以使用未记录的sp_MSforeactable过程,而不是循环或游标。类似下面的代码。我创建了运行您的代码并使用spmsforeachtable执行的过程。缺点是-该过程没有文档记录,在下一个SQL Server版本中可能不受支持

IF OBJECT_ID('dbo.usp_cleanup') IS NULL
    EXEC ('CREATE PROCEDURE dbo.usp_cleanup AS SELECT 1')
GO

ALTER PROCEDURE dbo.usp_cleanup
    @sTblName VARCHAR(200)
AS
BEGIN
    -- your variables
    DECLARE @PurgeDate  VARCHAR(50)
    DECLARE @SQL        VARCHAR(MAX)

    SET @PurgeDate      = DATEADD(MONTH, -6, GETUTCDATE())

    -- we can check columns existence in one condition
    IF
        EXISTS(SELECT * FROM sys.columns WHERE name = 'deleted' AND OBJECT_ID = OBJECT_ID(@sTblName)) 
        AND EXISTS(SELECT * FROM sys.columns WHERE name = 'LastUpdatedUtc' AND OBJECT_ID = OBJECT_ID(@sTblName))
        BEGIN
            SET @SQL = 'SQL CODE GOES HERE' -- this will be the delete line when the code is final, just outputting results for now
            PRINT @SQL
            --EXEC(@SQL)                    -- uncomment for execution
        END
    ELSE
    -- for debugging
        BEGIN
            PRINT @sTblName + ' has no [delete] and [LastUpdatedUtc] columns'
        END
END


EXEC sp_MSforeachtable 'exec usp_cleanup ''?'''
GO

您已经非常清楚地描述了要实现的步骤:遍历所有表、检查列、删除具有特定值的行;到目前为止,你编码了什么?你有什么困难?对于每个投反对票的人,我只需要50个代表,这样我就可以在任何地方发表评论了!谢谢你的指点,我编辑了我的帖子并添加了我的想法