【问题标题】:Loop through a table without using a cursor or temp table finding records over 30 days old在不使用游标或临时表查找超过 30 天的记录的情况下循环遍历表
【发布时间】:2017-12-21 23:27:38
【问题描述】:

使用 SQL Server 2012。我需要在不使用游标或临时表的情况下遍历我的表。另外,我知道辩论 re: cursors... :) 而且我在这个问题的底部有脚本,使用 sys.databases 和 msdb.dbo.restorehistory 得到最后恢复,但这并不能解决我对此的迫切需要具体表。

场景:我有一个为恢复测试创建的表:

CREATE Table RestoreTests (
RestoreTestID int Not NULL, 
ServerName varchar (255) Not NULL, 
DatabaseName varchar (255) Not NULL, 
RestoreDate datetime Not NULL,
BackupFile varchar (1000) Not NULL)

我插入了 8 条记录:

  • 2 个服务器 - 4 个记录/服务器,
  • .bak 和 .trn 用于每个 DatabaseName,以及
  • 日期 30 天 - 每个记录 4 条。

我想识别我的表中所有超过 30 天的记录。

SELECT * FROM RestoreTests WHERE RestoreDate DATEDIFF(Day,RestoreDate, GETDATE()) > 30

我的语法:

declare @RestoreTestID int
declare @ServerName varchar(255)
declare @DatabaseName varchar(255)
declare @RestoreDate datetime
declare @BackupFile varchar(1000)
declare @id int

set @id = 0

select top 1 @RestoreTestID = RestoreTestID,
@ServerName = ServerName,
@DatabaseName = DatabaseName,
@RestoreDate = RestoreDate,
@BackupFile = BackupFile
from dbo.RestoreTests
where RestoreTestID > @id and DATEDIFF(DAY,RestoreDate, GETDATE()) > 30
order by RestoreTestID asc

while @@ROWCOUNT > 0
begin

    print 'loop RestoreTestID=' + cast(@RestoreTestID as varchar(255)) +
    ', ServerName=' + @ServerName +
    ', DatabaseName' + @DatabaseName +
    ', RestoreDate' + CAST(@RestoreDate as varchar(255)) +
    ', BackupFile' + @BackupFile

    set @id = @RestoreTestID

    select top 1 @RestoreTestID = RestoreTestID
    from dbo.RestoreTests
    where RestoreTestID > @id and DATEDIFF(DAY,RestoreDate, GETDATE()) > 30
    order by RestoreTestID 

结束

我收到错误消息: 消息 137,第 15 级,状态 1,第 1 行 必须声明标量变量“@RestoreTestID”。 消息 137,第 15 级,状态 2,第 13 行 必须声明标量变量“@RestoreTestID”。 消息 137,第 15 级,状态 2,第 19 行 必须声明标量变量“@RestoreTestID”。 消息 137,第 15 级,状态 1,第 21 行 必须声明标量变量“@RestoreTestID”。

当我早些时候在附近用餐时,我确实得到了一个包含所有 8 条记录的结果集,而不是超过 30 天的 4 条记录。非常感谢您提供的任何帮助!

Last Restore Syntax:
WITH LastRestores AS
(
SELECT
    DatabaseName = [d].[name] ,
    [d].[create_date] ,
    [d].[compatibility_level] ,
    [d].[collation_name] ,
    r.*,
    RowNum = ROW_NUMBER() OVER (PARTITION BY d.Name ORDER BY r.[restore_date] DESC)
FROM master.sys.databases d
LEFT OUTER JOIN msdb.dbo.[restorehistory] r ON r.[destination_database_name] = d.Name
)
SELECT * 
FROM [LastRestores]
WHERE [RowNum] = 1


select * from [dbo].[RestoreTests]

【问题讨论】:

    标签: sql-server-2012-express


    【解决方案1】:

    好的,我知道我需要什么了。这是我得出的语法:

    declare @RestoreTestID int
    declare @id int
    declare @ServerName varchar(255);
    declare @DatabaseName varchar (255);
    declare @RestoreDate datetime;
    declare @BackupFile varchar (1000);
    
    set @id = 0
    
    select top 1 
        @RestoreTestID = RestoreTestID,
        @ServerName = ServerName,
        @DatabaseName = DatabaseName,
        @RestoreDate = RestoreDate,
        @BackupFile = BackupFile
    from dbo.RestoreTests
    where RestoreTestID > @id and RestoreDate <= DATEADD(day,-31,getdate())
    order by RestoreTestID
    
    while @@ROWCOUNT = 1
    begin
    
        print 'RestoreTestID = ' + cast(@RestoreTestID as varchar(255)) +
        ', ServerName = ' + @ServerName +
        ', Databasename = ' + @DatabaseName +
        ', RestoreDate = ' + cast(@RestoreDate as varchar (255)) +
        ', BackupFile = ' + @BackupFile
    
        set @id = @RestoreTestID
    
        select top 1 @RestoreTestID = RestoreTestID 
        from dbo.RestoreTests
        where RestoreTestID > @id and RestoreDate <= DATEADD(day,-31,getdate())
        order by RestoreTestID 
    
    end 
    

    【讨论】:

      猜你喜欢
      • 2013-02-27
      • 2010-09-08
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多