【问题标题】:How to get user from transaction log file In SQL Server (.ldf file) without app like ApexSqlLog如何在没有像 ApexSqlLog 这样的应用程序的情况下在 SQL Server(.ldf 文件)中从事务日志文件中获取用户
【发布时间】:2012-10-08 23:31:45
【问题描述】:

如何从 SQL Server 的事务日志文件中获取用户?

我尝试了这个查询,但它没有给我正确的用户

SELECT 
CASE 
  WHEN (SELECT NAME 
          FROM SYS.SERVER_PRINCIPALS lgn 
         WHERE Rtrim(lgn.SID) = Rtrim(log2.[TRANSACTION SID])) IS NOT 
       NULL THEN 
  'login: ' 
+ Upper((SELECT NAME FROM SYS.SERVER_PRINCIPALS lgn WHERE Rtrim(lgn.SID) 
  = Rtrim 
(log2.[TRANSACTION SID]))) 
  ELSE 'db user: ' 
       + Upper((SELECT NAME FROM SYS.SERVER_PRINCIPALS lgn WHERE Rtrim( 
       lgn.SID) 
       = Rtrim(log2.[TRANSACTION SID] ))) 
END 
AS 'Login_or_User', 
log1.*, 
CASE log1.__$OPERATION 
  WHEN 1 THEN 'DELETE' 
  WHEN 2 THEN 'INSERT' 
  WHEN 4 THEN 'UPDATED VALUE' 
  WHEN 3 THEN 'PREVIOUS UPDATED VALUE' 
  ELSE NULL 
END 
AS operation, 
CONVERT(VARCHAR(19), log2.[BEGIN TIME])                                                                                                                 AS 'Begin Time',
LEFT(log.ALLOCUNITNAME, Charindex('.', log.ALLOCUNITNAME) - 1) 
AS 'Schema', 
LEFT(RIGHT(log.ALLOCUNITNAME, Len(log.ALLOCUNITNAME) - 
                                   Charindex('.', log.ALLOCUNITNAME)), 
Charindex('.', RIGHT(log.ALLOCUNITNAME, 
Len(log.ALLOCUNITNAME) 
- 
                                                                                                               Charindex('.', log.ALLOCUNITNAME))) - 1) AS 'Object',
SYS.Fn_cdc_hexstrtobin(Substring(log.[CURRENT LSN], 1, 8) 
                       + Substring(log.[CURRENT LSN], 10, 8) 
                       + 
Substring(log.[CURRENT LSN], 19, 4))                                                                                           currentlsn
  FROM DBO.TEMPTABLE log1 
       LEFT JOIN ::FN_DBLOG(NULL, NULL) log 
              ON log1.__$SEQVAL = SYS.Fn_cdc_hexstrtobin( 
                                  Substring(log.[CURRENT LSN], 1, 8) 
                                  + Substring(log.[CURRENT LSN], 10, 8) 
                                  + Substring(log.[CURRENT LSN], 19, 4)) 
       LEFT JOIN ::FN_DBLOG(NULL, NULL)log2 
              ON log.[TRANSACTION ID] = log2.[TRANSACTION ID] 
       LEFT JOIN SYS.ALLOCATION_UNITS au 
              ON log.ALLOCUNITID = au.ALLOCATION_UNIT_ID 
       LEFT JOIN SYS.PARTITIONS p 
              ON p.PARTITION_ID = au.CONTAINER_ID 
       LEFT JOIN SYS.OBJECTS so 
              ON so.OBJECT_ID = p.OBJECT_ID 
       LEFT JOIN SYS.SERVER_PRINCIPALS spa 
              ON spa.SID = log2.[TRANSACTION ID] 

此代码用于检查启用了 CDC(CHange Data Capture) 的数据库,然后选择特定表以获取其更改

【问题讨论】:

  • 你想达到什么目的? Log2 是什么?
  • 您通常不会读取事务日志文件 - 这是一个内部 SQL Server 文件,并且没有记录的 API 可以读取事务日志文件目录。顺便说一句,您拥有的代码也不会读取事务日志文件...您要做什么,否则您无法做到?!?!?
  • 我想使用 Cdc(更改数据捕获)获取谁更改数据(插入-删除-更新),但您无法使用特定数据库的日志文件获取用户 >
  • @alex - 看起来 log2 是未记录(但非常有用)的 sys.fn_dblog 函数的别名。 Marc - 确实从事务日志中读出
  • 是的,在他提出相关问题之前,我们都发表了评论

标签: sql sql-server tsql


【解决方案1】:

您始终可以在表上放置一个触发器,以捕获针对该表插入、更新或删除数据的任何用户的 PK、getdate() 和 suser_id()。然后,您可以与 CDC 一起跟踪它以获得您想要的结果。我知道人们希望远离触发器,但它是一个简单易行的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    相关资源
    最近更新 更多