前言
等保要求去掉admin账户,并且删除所有admin产生的日志。
由于数据库太多,一个一个找太麻烦,于是就有了这篇文章:
总体思路:
- 遍历所有用户数据库
- 表名匹配
%LOG% - 确保有
user_name字段 - 支持任意 Schema
sql
-- 创建临时表存储所有 DELETE 语句
CREATE TABLE #DeleteStatements (DeleteStatement NVARCHAR(4000));
DECLARE @dbname SYSNAME;
DECLARE @sql NVARCHAR(MAX);
-- 声明局部游标(避免命名冲突)
DECLARE db_cursor CURSOR LOCAL FOR
SELECT name
FROM sys.databases
WHERE database_id > 4 -- 排除系统数据库
AND state = 0 -- 在线
AND is_read_only = 0; -- 可写
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO @dbname;
WHILE @@FETCH_STATUS = 0
BEGIN
-- 动态构建查询:找出当前库中 表名含 LOG + 有 user_name 列 的表,并生成 DELETE 语句
SET @sql = N'
INSERT INTO #DeleteStatements (DeleteStatement)
SELECT
''DELETE FROM '' +
QUOTENAME(''' + @dbname + ''') + ''.'' +
QUOTENAME(s.name) + ''.'' +
QUOTENAME(t.name) +
'' WHERE user_name = ''''admin'''';''
FROM ' + QUOTENAME(@dbname) + N'.sys.tables t
INNER JOIN ' + QUOTENAME(@dbname) + N'.sys.schemas s ON t.schema_id = s.schema_id
INNER JOIN ' + QUOTENAME(@dbname) + N'.sys.columns c ON t.object_id = c.object_id
WHERE UPPER(t.name) LIKE ''%LOG%''
AND c.name = ''user_name''
GROUP BY s.name, t.name;
';
BEGIN TRY
EXEC sp_executesql @sql;
END TRY
BEGIN CATCH
-- 忽略无法访问的数据库(如权限不足、脱机等)
PRINT 'Skipped database: ' + @dbname + ' (' + ERROR_MESSAGE() + ')';
END CATCH
FETCH NEXT FROM db_cursor INTO @dbname;
END
CLOSE db_cursor;
DEALLOCATE db_cursor;
-- 一次性返回所有 DELETE 语句(单个结果集)
SELECT DeleteStatement FROM #DeleteStatements ORDER BY DeleteStatement;
-- 清理
DROP TABLE #DeleteStatements;