Tenemos una base de datos SQL Server que tiene una especificación de auditoría de base de datos que audita todas las acciones de ejecución en la base de datos.
CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])
Hemos encontrado que algunas consultas escribirán en el registro de auditoría el uso de una función escalar para cada fila en un conjunto de resultados. Cuando esto sucede, el registro se llena antes de que podamos colocarlo en su lugar de descanso final y tenemos un espacio en nuestro registro.
Desafortunadamente, debido a razones de cumplimiento, no podemos simplemente dejar de auditar cada EXECUTE
declaración.
Nuestro primer pensamiento para el enfoque de este problema es usar una WHERE
cláusula en la Auditoría del servidor para filtrar la actividad. El código se veía así:
WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )
Desafortunadamente, SQL Server no permite el operador IN relacional (probablemente porque no quiere consultar cada vez que tiene que escribir en el registro de auditoría).
Nos gustaría evitar escribir un proceso almacenado que codifique object_id
en la WHERE
cláusula, pero ese es nuestro pensamiento actual sobre la mejor manera de abordar este problema. ¿Existe un enfoque alternativo que deberíamos considerar?
Hemos observado que cuando la función escalar está en uso en un CTE recursivo, hace que la consulta escriba en el registro de auditoría para cada fila del conjunto de resultados.
Hay algunas funciones de valor escalar entregadas por un proveedor que no podemos eliminar o mover a una base de datos alternativa.
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.
- Ese es uno de los efectos secundarios más magníficos de los UDF escalares que he escuchado, y he escuchado mucho.Respuestas:
Hay algunas opciones que pude poner a trabajar. Todas las opciones tratan con variaciones de predicados de filtro. NOTA: debe deshabilitar la Auditoría del servidor para realizar cambios y luego volver a habilitarla .
Primero, el enfoque más genérico es filtrar todos los UDF escalares. Puede hacerlo utilizando el
class_type
campo de auditoría. La documentación indica que este campo esVARCHAR(2)
, pero no permite especificar una cadena. Sin embargo, conseguí que funcionara lo siguiente:(Más información sobre esa investigación aquí: misterio de auditoría del servidor: el filtrado de class_type obtiene el mensaje de error 25713 )
El siguiente enfoque más genérico no es una opción, ya que se dijo que esta es una base de datos suministrada por el proveedor y, por lo tanto, no se pueden realizar cambios. Así que cubriré eso último.
El enfoque menos genérico (pero definitivamente funciona) es filtrar el nombre de la función específica:
O, si hay varios nombres:
Si bien no es muy genérico, este enfoque debería estar bien, ya que el número de funciones para filtrar debería ser bastante pequeño, y no será muy frecuente que se introduzcan nuevas funciones.
Finalmente, para otros que enfrentan esta situación y no tienen restricciones para realizar cambios: puede colocar funciones en su propio esquema y luego filtrar solo ese esquema. Esto es más genérico que filtrar las funciones individualmente. Suponiendo que cree un Esquema llamado
fn
y coloque las funciones en él:TAMBIÉN, con respecto a los siguientes dos comentarios en la pregunta:
y:
El
IN
operador no es el problema. Es cierto que no es compatible, pero es solo una forma abreviada de una lista deOR
condiciones. El problema real es el uso de T-SQL. Solo se permiten literales (cadenas o números). Por lo tanto, no habría podido ejecutar un Procedimiento almacenado de todos modos. Tampoco puedes usar las funciones integradas.fuente
=
para estar<>
en mi respuesta. También lo probé y funciona como se anuncia :-)