我有一份备份报告,查看是否在过去 30 天内备份了所有数据库,并希望在该字段(日期时间类型)中插入“并非所有数据库在过去 30 天内备份”,如果是这种情况在过去 30 天内并非所有数据库都已备份,但我收到错误消息Conversion failed when converting date and/or time from character string
。
;WITH CTE AS
(
SELECT
--sdb.Name AS DatabaseName,
MAX(backup_finish_date) AS LastBackUpTime
FROM sys.databases sdb
LEFT OUTER JOIN msdb.dbo.backupset bus ON bus.database_name = sdb.name
WHERE bus.type = 'D'AND bus.database_name NOT IN ('master', 'model', 'msdb', 'tempdb') AND bus.backup_finish_date > DATEADD(day,-30,GETDATE())
AND sdb.Name NOT IN ('DBA')
AND sdb.state_desc = 'ONLINE'
--GROUP BY sdb.Name
)
INSERT INTO Server.Database.Schema.TableName
SELECT @@SERVERNAME as serverName,
--DatabaseName as DatabaseName,
CASE WHEN LastBackupTime IS NULL THEN 'Not all databases backed up in last 30 days' ELSE MIN(LastBackUpTime) END as LastBackUpTime
FROM CTE
GROUP BY LastBackUpTime
如果尚未备份任何数据库,则以下内容应返回“未备份所有数据库”,如果已备份,则应返回“从 DD/MM/YYYY 开始备份的所有数据库”(这将是找到的最高备份日期)
该脚本查找所有非系统(和非 DBA)数据库的最高备份日期,如果没有,则返回等效于 0 的日期时间(这将转换为
1900-01-01 00:00:00.000
)。然后我们可以检查最短日期是否在我们的 30 天区域内。您遇到的实际问题是因为您的 CASE 语句同时返回了 DATETIME 数据类型和 VARCHAR 数据类型 - 因为 CASE 语句的数据类型优先级,SQL 服务器将始终选择最高优先级的数据类型作为该数据类型字段 - 在本例中为 DATETIME。
为了防止这种情况,我们只需将 DATETIME 字段转换为 VARCHAR,这可以防止从 VARCHAR 到 DATETIME 的隐式转换(从低到高优先级)