Temos um banco de dados SQL Server que possui uma especificação de auditoria de banco de dados que audita todas as ações de execução no banco de dados.
CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])
Descobrimos que algumas consultas gravam no log de auditoria o uso de uma função escalar para cada linha de um conjunto de resultados. Quando isso acontece, o registro é preenchido antes que possamos colocá-lo em ETL em seu local de descanso final e temos uma lacuna em nosso registro.
Infelizmente, devido a motivos de conformidade, não podemos simplesmente parar de auditar todas as EXECUTE
declarações.
Nosso primeiro pensamento para abordar esse problema é usar a WHERE
cláusula na Auditoria do Servidor para filtrar a atividade. O código ficou assim:
WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )
Infelizmente, o SQL Server não permite o operador IN relacional (provavelmente porque não deseja consultar toda vez que precisar gravar no log de auditoria).
Gostaríamos de evitar escrever um processo armazenado que codifique a cláusula object_id
na WHERE
cláusula, mas esse é o nosso pensamento atual sobre a melhor maneira de abordar esse problema. Existe uma abordagem alternativa que devemos considerar?
Percebemos que, quando a função escalar está em uso em um CTE recursivo, ela faz com que a consulta grave no log de auditoria de todas as linhas do conjunto de resultados.
Existem algumas funções avaliadas escalares que são entregues por um fornecedor que não podemos excluir ou mover para um banco de dados alternativo.
We've found that some queries will write to the audit log the use of a scalar function for every row in a result set.
- Esse é um dos efeitos colaterais mais magníficos das UDFs escalares que eu já ouvi e ouvi muito.