Audit Scripts: General Audit

Audit Scripts: General Audit

After completing a backup there are a number of things that are good to review prior to restoring into the destination system. 

The script below reviews several of the data points that should be looked at prior to restoring. 
This script is not exhaustive, but it is a good place to start when looking for anomalies. 
  1.   SELECT * FROM 
  2. (

  3. --Look for custom fields that aren't being used.
  4. SELECT
  5. 0 sortOrder,
  6. '__M_CustomField_Definitions' tableName,
  7. cfd.Final_Status,
  8. IIF(COALESCE(cfv.Final_CustomFieldDefinition_Id, '')='', 'Custom Field Not Used', 'Custom Field Used') auditDescription,
  9. COUNT(*) numRows,
  10.   (SELECT COUNT(*) FROM __M_CustomField_Definitions) totalRows
  11.   FROM
  12. __M_CustomField_Definitions cfd
  13. LEFT OUTER JOIN
  14. (SELECT Final_CustomFieldDefinition_Id FROM __M_CustomField_Values GROUP BY Final_CustomFieldDefinition_Id) cfv
  15. ON cfd.Id = cfv.Final_CustomFieldDefinition_Id
  16. GROUP BY
  17. cfd.Final_Status,
  18. IIF(COALESCE(cfv.Final_CustomFieldDefinition_Id, '')='', 'Custom Field Not Used', 'Custom Field Used')

  19. UNION ALL

  20. -- Look for used/unused practice areas.

  21. SELECT
  22.    1 AS sortOrder,
  23.     '__M_Matters_PracticeAreas' AS tableName,
  24.     pa.Final_Status,
  25.     IIF(COALESCE( m.Final_PracticeArea_Id, '') = '', 'Practice Area Not Used', 'Practice Area Used') auditDescription,
  26.     SUM(CASE WHEN m.Final_PracticeArea_Id IS NOT NULL THEN 1 ELSE 0 END) AS numRows,
  27.     (SELECT COUNT(*) FROM __M_Matters_PracticeAreas) AS totalRows
  28. FROM
  29.     __M_Matters_PracticeAreas pa
  30. LEFT JOIN
  31.     (SELECT Final_PracticeArea_Id FROM __M_Matters GROUP BY Final_PracticeArea_Id) m
  32. ON 
  33.     pa.Id = m.Final_PracticeArea_Id
  34. GROUP BY
  35.     pa.Final_Status,
  36. IIF(COALESCE( m.Final_PracticeArea_Id, '') = '', 'Practice Area Not Used', 'Practice Area Used')

  37. UNION ALL

  38. -- Look for contacts with no names
  39. SELECT
  40. 2 sortOrder,
  41. '__M_Contacts' tableName,
  42. Final_Status,
  43. IIF( Final_FirstName = '' AND Final_LastName = '' AND Final_FullName = '', 'No Name', 'Has Name') auditDescription,
  44. COUNT(*) numRows,
  45. (SELECT COUNT(*) FROM __M_Contacts) totalRows
  46. FROM
  47. __M_Contacts
  48. GROUP BY
  49. Final_Status,
  50. IIF( Final_FirstName = '' AND Final_LastName = '' AND Final_FullName = '', 'No Name', 'Has Name')

  51. UNION ALL

  52. -- Look for Matters missing descriptors
  53. SELECT
  54. 2.5 sortOrder,
  55. '__M_Matters' tableName,
  56. Final_Status,
  57. IIF( Final_Subject = '' AND Final_Description = '' AND Final_ReferenceCode = '', 'No Descriptors', 'Has Descriptors') auditDescription,
  58. COUNT(*)  numRows,
  59. (SELECT COUNT(*) FROM __M_Matters) totalRows
  60. FROM
  61. __M_Matters
  62. GROUP BY
  63. Final_Status,
  64. IIF( Final_Subject = '' AND Final_Description = '' AND Final_ReferenceCode = '', 'No Descriptors', 'Has Descriptors') 

  65. UNION ALL

  66. SELECT
  67. 2.61 sortOrder,
  68. '__M_Matters' tableName,
  69. 'All Statuses' Final_Status,
  70. CONCAT('Max Description Len - ', MAX(LEN(Final_Description))) auditDescription,
  71. COUNT(*)  numRows,
  72. (SELECT COUNT(*) FROM __M_Matters) totalRows
  73. FROM
  74. __M_Matters

  75. UNION ALL

  76. SELECT
  77. 2.6 sortOrder,
  78. '__M_Matters' tableName,
  79. 'All Statuses' Final_Status,
  80. CONCAT('Min Description Len - ', MIN(LEN(Final_Description))) auditDescription,
  81. COUNT(*)  numRows,
  82. (SELECT COUNT(*) FROM __M_Matters) totalRows
  83. FROM
  84. __M_Matters

  85. UNION ALL

  86. SELECT
  87. 2.62 sortOrder,
  88. '__M_Matters' tableName,
  89. 'All Statuses' Final_Status,
  90. CONCAT('Min ReferenceCode Len - ', MIN(LEN(Final_ReferenceCode))) auditDescription,
  91. COUNT(*)  numRows,
  92. (SELECT COUNT(*) FROM __M_Matters) totalRows
  93. FROM
  94. __M_Matters

  95. UNION ALL

  96. SELECT
  97. 2.63 sortOrder,
  98. '__M_Matters' tableName,
  99. 'All Statuses' Final_Status,
  100. CONCAT('Max ReferenceCode Len - ', MAX(LEN(Final_ReferenceCode))) auditDescription,
  101. COUNT(*)  numRows,
  102. (SELECT COUNT(*) FROM __M_Matters) totalRows
  103. FROM
  104. __M_Matters

  105. UNION ALL

  106. SELECT
  107. 2.64 sortOrder,
  108. '__M_Matters' tableName,
  109. 'All Statuses' Final_Status,
  110. CONCAT('Min Subject Len - ', MIN(LEN(Final_Subject))) auditDescription,
  111. COUNT(*)  numRows,
  112. (SELECT COUNT(*) FROM __M_Matters) totalRows
  113. FROM
  114. __M_Matters

  115. UNION ALL

  116. SELECT
  117. 2.65 sortOrder,
  118. '__M_Matters' tableName,
  119. 'All Statuses' Final_Status,
  120. CONCAT('Max Subject Len - ', Max(LEN(Final_Subject))) auditDescription,
  121. COUNT(*)  numRows,
  122. (SELECT COUNT(*) FROM __M_Matters) totalRows
  123. FROM
  124. __M_Matters

  125. UNION ALL

  126. -- Look for activities billed/unbilled status
  127. SELECT
  128. 3 sortOrder,
  129. '__M_Financial_Activities_Expenses' tableName,
  130. Final_Status,
  131. IIF( Final_ArInvoice_Id = '', 'Unbilled', 'Billed' ) auditDescription,
  132. COUNT(*) numRows,
  133. (SELECT COUNT(*) FROM __M_Financial_Activities_Expenses) totalRows
  134. FROM
  135. __M_Financial_Activities_Expenses
  136. GROUP BY
  137. Final_Status,
  138. IIF( Final_ArInvoice_Id = '', 'Unbilled', 'Billed' )

  139. UNION ALL

  140. SELECT
  141. 3.1 sortOrder,
  142. '__M_Financial_Activities_Fees' tableName,
  143. Final_Status,
  144. IIF( Final_ArInvoice_Id = '', 'Unbilled', 'Billed' ) auditDescription,
  145. COUNT(*) numRows,
  146. (SELECT COUNT(*) FROM __M_Financial_Activities_Fees) totalRows
  147. FROM
  148. __M_Financial_Activities_Fees
  149. GROUP BY
  150. Final_Status,
  151. IIF( Final_ArInvoice_Id = '', 'Unbilled', 'Billed' )

  152. UNION ALL

  153. SELECT
  154. 3.2 sortOrder,
  155. '__M_Financial_Activities_Expenses' tableName,
  156. Final_Status,
  157. IIF( Final_ArInvoice_Id = '', 'Unbilled', 'Billed' ) auditDescription,
  158. COUNT(*) numRows,
  159. (SELECT COUNT(*) FROM __M_Financial_Activities_Expenses) totalRows
  160. FROM
  161. __M_Financial_Activities_Expenses
  162. GROUP BY
  163. Final_Status,
  164. IIF( Final_ArInvoice_Id = '', 'Unbilled', 'Billed' )

  165. UNION ALL

  166. --Look at Invoice Outstanding/not Outstanding balance counts.
  167. SELECT
  168. 3.3 sortOrder,
  169. '__M_Financial_AR_Invoices' tableName,
  170. Final_Status,
  171. IIF( Final_Outstanding_Override > 0, 'Outstanding Balance', 'No Outstanding Balance') auditDescription,
  172. COUNT(*) numRows,
  173. (SELECT COUNT(*) FROM __M_Financial_AR_Invoices) totalRows
  174. FROM
  175. __M_Financial_AR_Invoices
  176. GROUP BY
  177. Final_Status,
  178. IIF( Final_Outstanding_Override > 0, 'Outstanding Balance', 'No Outstanding Balance')

  179. UNION ALL

  180. -- Look for matters missing a contact
  181. SELECT
  182. 4 sortOrder,
  183. '__M_Matters' tableName,
  184. m.Final_Status,
  185. IIF(COALESCE(c.Id, '')='', 'Contact Missing', 'Contact Eists') auditDescription,
  186. COUNT(*) numRows,
  187. (SELECT COUNT(*) FROM __M_Matters) totalRows
  188. FROM
  189. __M_Matters m
  190. LEFT OUTER JOIN
  191. __M_Contacts c
  192. ON m.Final_ClientContact_Id = c.Id
  193. GROUP BY
  194. m.Final_Status,
  195. IIF(COALESCE(c.Id, '')='', 'Contact Missing', 'Contact Eists')

  196. UNION ALL

  197. -- Look for documents linked to matters with a missing matter reference.
  198. SELECT
  199. 5 sortOrder,
  200. '__M_Documents_Digital_Files'  tableName,
  201. df.Final_Status,
  202. IIF(COALESCE(m.Id, '')='', 'Matter Missing', 'Matter Exists') auditDescription,
  203. COUNT(*) numRows,
  204. (SELECT COUNT(*) FROM __M_Documents_Digital_Files) totalRows
  205. FROM
  206. __M_Documents_Digital_Files df
  207. LEFT OUTER JOIN
  208. __M_Matters m
  209. ON df.Final_Parent_Id= m.Id
  210. WHERE 1=1
  211. AND df.Final_Parent_Type = '__M_Matters'
  212. GROUP BY
  213. df.Final_Status,
  214. IIF(COALESCE(m.Id, '')='', 'Matter Missing', 'Matter Exists')

  215. UNION ALL

  216. -- Look for documents linked to Contacts with a missing Contact reference.
  217. SELECT
  218. 5.1 sortOrder,
  219. '__M_Documents_Digital_Files' tableName,
  220. df.Final_Status,
  221. IIF(COALESCE(c.Id, '')='', 'Orphan Contacts', 'Contact Exists') auditDescription,
  222. COUNT(*) numRows,
  223. (SELECT COUNT(*) FROM __M_Documents_Digital_Files) totalRows
  224. FROM
  225. __M_Documents_Digital_Files df
  226. LEFT OUTER JOIN
  227. __M_Contacts c
  228. ON df.Final_Parent_Id= c.Id
  229. WHERE 1=1
  230. AND df.Final_Parent_Type = '__M_Contacts'
  231. GROUP BY
  232. df.Final_Status,
  233. IIF(COALESCE(c.Id, '')='', 'Orphan Contacts', 'Contact Exists')

  234. UNION ALL

  235. -- Look for Documents with/without content paths
  236. SELECT
  237. 5.2 sortOrder,
  238. '__M_Documents_Digital_Files' tableName,
  239. df.Final_Status,
  240. IIF(COALESCE(dfv.hasContentPath, 0)=0, 'No Content Path', 'Has Content Path') auditDescription,
  241. COUNT(*) numRows,
  242. (SELECT COUNT(*) FROM __M_Documents_Digital_Files) totalRows
  243. FROM
  244. __M_Documents_Digital_Files df
  245. LEFT OUTER JOIN
  246. (SELECT Final_DocumentFile_Id, SUM(IIF(Final_ContentPath='',0,1)) hasContentPath FROM __M_Documents_Digital_Files_Versions GROUP BY
  247. Final_DocumentFile_Id) dfv
  248. ON df.Id = dfv.Final_DocumentFile_Id
  249. GROUP BY
  250. df.Final_Status,
  251. IIF(COALESCE(dfv.hasContentPath, 0)=0, 'No Content Path', 'Has Content Path')
  252. ) T
  253. ORDER BY
  254. sortOrder, tableName, auditDescription

    • Related Articles

    • Audit Scripts: Activity Billed/Unbilled row counts

      After you have backed up financial information like Time Entries, Expense Entries, and Fee Entries it is a good idea to audit the results prior to restoring data to the destination system. For example, some Universal Destinations support restoring ...
    • Audit Scripts: Row Counts and Progress Monitoring

      This article shows you a script that can be used to monitor the progress of both a Backup and a Restore. It can also be used to just review row counts on all the Universal Database tables. The first code block is used to populate a SQL Server Temp ...
    • Synthesize Missing Matters for Documents

      Some systems only allow documents to be linked to matters. These scripts will allow you to restore data into these systems. When Matters No Longer Exist The following script with synthesize matters for document related to matters that no longer ...
    • Other: Trimming Field Lengths

      Sometimes you may want to manually trim records so that they have certain lengths. The scripts below provide examples on how to best do this. --This is the max length you want DECLARE @MaxLength INT = 50 --This is the characters you want for an ...
    • Prioritizing documents based on different criteria

      The following scripts provide examples that can be modified to apply different priorities to documents. Prioritize Large/Small Documents If you are restoring into a system that has different action limits at different times, this can help you ...