Core component of SQL Server for storing, processing, and securing data
You found the mismatch. class_type_desc is the audit class name ("SQL USER"), while sys.dm_audit_actions.class_desc uses the securable class ("USER"). The class type map has a third column for exactly this: securable_class_desc, which Microsoft documents as the column to join with class_desc in sys.dm_audit_actions.
- Change the join to use
dc.securable_class_descinstead ofdc.class_type_desc. - Use LEFT JOINs, because
securable_class_desccan be NULL for class types that don't map to a securable, and you don't want to lose those events.
SELECT DISTINCT fng.event_time, fng.succeeded, fng.server_principal_name,
fng.database_name, fng.object_name, fng.statement,
fng.action_id, da.name AS action_name,
fng.class_type, dc.class_type_desc
FROM sys.fn_get_audit_file('C:\Audit\*.sqlaudit', DEFAULT, DEFAULT) AS fng
LEFT JOIN sys.dm_audit_class_type_map AS dc
ON dc.class_type = fng.class_type
LEFT JOIN sys.dm_audit_actions AS da
ON da.action_id = fng.action_id
AND da.class_desc = dc.securable_class_desc
ORDER BY fng.event_time DESC;
- Run it and check that your CR / SU event now shows the action name.
Does that row come back with the action name filled in?
If this fixed the query, please consider accepting it as the answer. If some events still show a blank action name, let me know and I'll be happy to keep helping.
Reference: