根据CRM视图获取任何实体记录的审核历史记录

时间:2017-08-03 11:18:07

标签: sql-server dynamics-crm crm dynamics-crm-2013

我想按照MS CRM格式显示所有审核历史数据。

enter image description here

我已将AuditBase表中的所有记录从CRM导入到另一个数据库服务器表。

我希望使用Dynamics CRM格式的SQL查询来记录此表记录(如上图所示)。

到目前为止我已经完成了

select 
AB.CreatedOn as [Created On],SUB.FullName [Changed By],
Value as Event,ab.AttributeMask [Changed Field],
AB.changeData [Old Value],'' [New Value] from Auditbase AB

inner join StringMap SM on SM.AttributeValue=AB.Action and SM.AttributeName='action'
inner join SystemUserBase SUB on SUB.SystemUserId=AB.UserId

--inner join MetadataSchema.Attribute ar on ab.AttributeMask = ar.ColumnNumber
--INNER JOIN MetadataSchema.Entity en ON ar.EntityId = en.EntityId and en.ObjectTypeCode=AB.ObjectTypeCode

--inner join Contact C on C.ContactId=AB.ObjectId
where objectid='00000000-0000-0000-000-000000000000' 
Order by AB.CreatedOn desc

我的问题是AttributeMask是一个逗号分隔的值,我需要与MetadataSchema.Attribute表的columnnumber字段进行比较。以及如何从该实体获得新价值。

我已经检查了这个链接:Sql query to get data from audit history for opportunity entity,但它没有给我[新值]。

注意:我不能使用" RetrieveRecordChangeHistoryResponse",因为我需要在sql table(非CRM数据库)的外部网页中显示这些数据。

3 个答案:

答案 0 :(得分:10)

嗯,基本上,Dynamics CRM不会使用SQL查询创建此审核视图(在CRM中看到它的方式),因此如果您成功完成此操作,Microsoft可能会从您那里购买它,因为它会比它目前处理的方式:)

但实际上 - 它当前的工作方式,SQL仅用于获取所有相关的审核视图记录(没有任何与属性元数据或其他任何匹配),然后,所有解析和与元数据的匹配都在.NET应用程序中完成。逻辑非常复杂,有很多不同的情况需要处理,我相信在SQL中重新创建它不仅需要一些简单的选择"查询,但实际上是一些非常复杂的过程(并且仍然可能还不够,因为并非CRM中的所有内容都保存在数据库中,有些东西只是编译到应用程序库中),而且一个人可能需要几周甚至几个月才能完成(当然,我认为,也许一些T-SQL大师会证明我错了。)

所以,我会采取不同的方式 - 使用RetrieveRecordChangeHistoryRequest(已经在一些答案中提到过)使用某种.NET应用程序获取所有审计详细信息(已经解析并可以使用)(可能正在运行)定期,或者可能由CRM等插件触发)并以用户友好的格式将它们放入某个数据库中。然后,您可以使用所需的任何外部应用程序使用此数据库。

我也不理解你的评论:

  

我不能使用" RetrieveRecordChangeHistoryResponse",因为我需要   从sql表(非CRM数据库)

在外部网页中显示这些数据

什么样的应用程序无法调用外部服务(您可以创建自定义服务,不必使用CRM服务)来获取某些数据,但是可以访问外部数据库吗?您不应该直接从数据库中读取,更好的方法是准备一个Web服务,返回您想要的审计(使用CRM SDK)并通过外部应用程序调用此服务。除非你的外部应用程序当然只能读取数据库,不能运行任何自定义Web服务......

答案 1 :(得分:5)

无法仅从AuditBase表重建完整的审计历史记录。对于当前值,您仍然需要正在审计的表。

您需要构建的查询很复杂,如果export const LOAD_PRODUCT_TREE = 'load-product-tree'; export const LOAD_PRODUCT_TREE_COMPLETE = 'load-product-tree-complete'; export const LOAD_PRODUCT_TREE_FAIL = 'load-product-tree-fail'; export const DELETE_BRANCH = 'delete-branch'; export const ADD_CHILD = 'add-child'; /** * Loads tree from backend and resets current state. */ export class LoadProductTreeAction implements Action { readonly type = LOAD_PRODUCT_TREE; constructor (public payload: number) { } } /** * Returns the loaded tree from the backend. */ export class LoadProductTreeCompleteAction implements Action { readonly type = LOAD_PRODUCT_TREE_COMPLETE; constructor (public payload: Map<number, Node>) { } } /** * Returns an error that happened when the tree was being loaded from the backend. */ export class LoadProductTreeFailAction implements Action { readonly type = LOAD_PRODUCT_TREE_FAIL; constructor (public payload: string) { } } /** * Deletes an entire branch of the tree (the current node and all child nodes). */ export class DeleteBranchAction implements Action { readonly type = DELETE_BRANCH; constructor (public payload: Node) { } } /** * Adds a child to a node. */ export class AddChildAction implements Action { readonly type = ADD_CHILD; constructor (public payload: { parent: Node, newChild: Node }) { } } export type Actions = LoadProductTreeAction | LoadProductTreeCompleteAction | LoadProductTreeFailAction | DeleteBranchAction | AddChildAction; 也是合适的选项,则可以避免编写它们。  (另请参阅SO上的How to get audit record details using FetchXML。)

  

注意

     

此答案是在原始问题延长之前提交的,表明RetrieveRecordChangeHistoryRequest无法使用。

答案 2 :(得分:-2)

正如我在评论中所说,审计表将具有旧的价值和新价值,但不是当前价值。当下次更新发生时,当前值将被推送为新值。

在您的OP查询中,ab.AttributeMask将返回逗号","分隔值,而AB.changeData将返回代字号"~"分隔值。

我认为您将"~"个值分隔为Old Value列的情况很好,希望在New Value列中显示字段的当前值。当为审计启用多个字段时,这不起作用。您必须使用Attribute mask&amp;将AttributeView字段值从ColumnNumber拆分为CRM字段。得到所需的结果。

我建议使用以下参考博客,一旦获得预期结果,您可以使用SQL中的额外查询或前端使用C#来提取当前字段值。但是您应该再次使用"~"连接值以保持格式。

https://marcuscrast.wordpress.com/2012/01/14/dynamics-crm-2011-audit-report-in-ssrs/

<强>更新
在上面的博客中,您可以使用您的字段调整SP查询,然后将最后一个select语句转换为&#39; select into&#39;为您的存储创建一个新表。

修改存储过程以根据上次运行获取增量。配置sql job&amp;计划每天运行一次,以填充表格。

然后选择&amp;以您希望的方式显示数据。我在3天内在PowerBI中做了同样的事情。

优点/缺点:显然此要求仅用于报告目的。全球报告要求将通过复制或其他方式镜像数据库,并且不会中断Prod用户和通过注入插件或任何随需应变的Adhoc服务调用来实现异步服务器。此外,您可以访问数据库&amp;不是CRM在线。最好不要重新发明轮子和轮子。推进可用的解决方案。这是我的拙见和基于Microsoft内部项目实现。