我想按照MS CRM格式显示所有审核历史数据。
我已将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数据库)的外部网页中显示这些数据。
答案 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内部项目实现。