Abbiamo un database SQL Server che ha una specifica di controllo del database che controlla tutte le azioni eseguite sul database.
CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])
Abbiamo scoperto che alcune query scriveranno nel registro di controllo l'uso di una funzione scalare per ogni riga in un set di risultati. Quando ciò accade, il registro si riempie prima che possiamo ETL nel suo luogo di riposo finale e abbiamo un gap nella nostra registrazione.
Sfortunatamente per motivi di conformità, non possiamo semplicemente smettere di controllare ogni EXECUTE
affermazione.
Il nostro primo pensiero per l'approccio a questo problema è utilizzare la WHERE
clausola su Server Audit per filtrare l'attività. Il codice era simile al seguente:
WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )
Sfortunatamente, SQL Server non consente l'operatore relazionale IN (probabilmente perché non desidera eseguire query ogni volta che deve scrivere nel registro di controllo).
Vorremmo evitare di scrivere un proc memorizzato che codifica in modo duro object_id
nella WHERE
clausola, ma questo è il nostro pensiero attuale sul modo migliore per affrontare questo problema. Esiste un approccio alternativo che dovremmo considerare?
Abbiamo notato che quando la funzione scalare è in uso in un CTE ricorsivo, fa sì che la query scriva nel registro di controllo per ogni riga del set di risultati.
Esistono alcune funzioni con valori scalari fornite da un fornitore che non è possibile eliminare o spostare in un database 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.
- Questo è uno dei più magnifici effetti collaterali degli UDF scalari che io abbia mai sentito, e ho sentito molto.