Friday 14 September 2012

Workaround for text editor error after applying update Rollup 10

MS CRM  2011 developers might not be too concerned with performing actual queries on live customer data, but they will certainly be annoyed when encountering the following prompt after editing a JavaScript web resource: "You have exceeded the maximum number of 200 characters in this field; it will be truncated."



Below is the workaround to work with editor

1.Open the editor.
2.Copy your code and paste it in editor.
3.Click OK button.
4.You will get the error prompt ""You have exceeded the maximum number of 200 characters in this field"
5.Press "Cancel" button on prompt.
6.Now press "OK" button on editor.
7.You can see that all your code has been copied  successfully without truncation.

Hope this helps, Enjoy Coding :) 

Thursday 13 September 2012

Removing duplicates using sql script in MS CRM 2011

Recently we have a requirement where we have to remove the duplicates records using sql query in MS CRM 2011.

To better understand the requirement let's describe entity and their relationship

Duplicate Entity :AccountMapping
Related entities related to AccountMapping  as below

Having 1:N relationship with AccountMapping

1) CSCall ( One Accountmapping can have multiple CSCalls)

Having N:1 relationship with AccountMapping
1)Account (One  Account can have multiple AccountMapping  )

Problem Screenshot



What we need to achieve

1)We need to remove the duplicate account mappings.
Example :If their are three duplicate Accountmapping having same AccountNumber then we need to delete
two duplicate Accountmapping

Challenges:Difficulty we were facing was that we have to update the references of the to be deleted duplicate AccountMapping to one AccountMapping records.
Example: If we have one account with two duplicate accountmapping(Say AM-1,AM-1) where first AM-1
is  referred by two CSCalls(Say CS-1,CS-2)and second AM-1 is  referred by one CSCall (Say- CS-3).
If  We are deleting the duplicate accountmapping say second AM-1 then we have to programatically
change the reference of CS-3 to first AM-1.

Refer below diagram to know the requirement.



Solution :
Query 1 :Sql script to get the  all Accounts which have duplicate Accountmapping

 

select new_accountid,new_accountidname,new_accountnumber,COUNT(1) as DuplicateRecordCount 
from Filterednew_accountmapping  am
inner join FilteredAccount ac on ac.accountid = am.new_accountid
where new_accountid is not  null ac.statecode =0 and am.statecode =0 
Group By new_accountid,new_accountidname,new_accountnumber
Having COUNT(1) >1

Query 2:Delete duplicates account mapping which do not referenced in CS Calls


begin tran
  
 delete from new_accountmappingExtensionBase
 
 where new_accountmappingid in
 (
 
 Select  distinct 
a.new_accountmappingid
From
(select  new_accountmappingid,A.new_accountid,A.new_accountidname,A.new_accountnumber from Filterednew_accountmapping CS
join(select new_accountid,new_accountidname,new_accountnumber,COUNT(1) as DuplicateRecordCount 
from Filterednew_accountmapping  am
inner join FilteredAccount ac on ac.accountid = am.new_accountid
 where new_accountid is not  null and ac.statecode =0    and am.statecode =0
--where Am.new_accountidname='Village Vet of Urbana'
Group By new_accountid,new_accountidname,new_accountnumber
Having COUNT(1) >1)A
on CS.new_accountid=A.new_accountid And
CS.new_accountidname=A.new_accountidname And
CS.new_accountnumber=A.new_accountnumber)A
left outer Join Filterednew_cscase C
on A.new_accountmappingid=c.new_cscallaccountmappingid 
 where C.new_cscallaccountmappingid  is null
 
 )

Final Query :Making use of above sql queries Query 1Query2 also we have written a CURSOR which updates the references of CSCalls and deletes the duplicate Accountmapping.
 -------------------------------------------------------------------------------
 -- Delete duplicates account mapping which do not referenced in CS Calls
 -------------------------------------------------------------------------------

begin tran
  
 delete from new_accountmappingExtensionBase
 
 where new_accountmappingid in
 (
 
 Select  distinct 
a.new_accountmappingid
From
(select  new_accountmappingid,A.new_accountid,A.new_accountidname,A.new_accountnumber from Filterednew_accountmapping CS
join(select new_accountid,new_accountidname,new_accountnumber,COUNT(1) as DuplicateRecordCount 
from Filterednew_accountmapping  am
inner join FilteredAccount ac on ac.accountid = am.new_accountid
 where new_accountid is not  null and ac.statecode =0    and am.statecode =0
Group By new_accountid,new_accountidname,new_accountnumber
Having COUNT(1) >1)A
on CS.new_accountid=A.new_accountid And
CS.new_accountidname=A.new_accountidname And
CS.new_accountnumber=A.new_accountnumber)A
left outer Join Filterednew_cscase C
on A.new_accountmappingid=c.new_cscallaccountmappingid 
 where C.new_cscallaccountmappingid  is null
 
 
 )
 
 -------------------------------------------------------------------------------
 -- Update CS Call reference and delete duplicates account mapping
 -------------------------------------------------------------------------------
 --rollback tran
begin tran

DECLARE @Accountid uniqueidentifier, @AccountName nvarchar(100), @AccountNumber nvarchar(100), @AccountMapId uniqueidentifier

DECLARE My_cursor CURSOR FOR 

select new_accountid,new_accountidname
from Filterednew_accountmapping  am
inner join FilteredAccount ac on ac.accountid = am.new_accountid
where new_accountid is not  null and ac.statecode =0
Group By new_accountid,new_accountidname,new_accountnumber
Having COUNT(1) >1

OPEN My_cursor

FETCH NEXT FROM My_cursor INTO @Accountid, @AccountName

WHILE @@FETCH_STATUS = 0
BEGIN

 Select  distinct TOP 1
 @AccountMapId = a.new_accountmappingid, @AccountNumber = a.new_accountnumber  From
 (select  new_accountmappingid,A.new_accountid,A.new_accountidname,A.new_accountnumber from Filterednew_accountmapping CS
 join(select new_accountid,new_accountidname,new_accountnumber,COUNT(1) as DuplicateRecordCount 
 from Filterednew_accountmapping  am
 inner join FilteredAccount ac on ac.accountid = am.new_accountid
 
 where Am.new_accountid=@Accountid and 
 ac.statecode =0 and am.statecode =0
 Group By new_accountid,new_accountidname,new_accountnumber
 Having COUNT(1) >1)A
 on CS.new_accountid=A.new_accountid And
 CS.new_accountidname=A.new_accountidname And
 CS.new_accountnumber=A.new_accountnumber)A
 left outer Join Filterednew_cscase C
 on A.new_accountmappingid=c.new_cscallaccountmappingid
 where C.new_cscallaccountmappingid  is  not null
 
 
 update c Set 
  c.new_cscallaccountmappingid = @AccountMapId   
  From new_cscase c WHERE
  c.new_cscallaccountmappingidname = @AccountNumber and c.new_accountnameid = @Accountid
  
 
  delete from new_accountmappingExtensionBase WHERE
  new_accountid = @Accountid and new_accountmappingid != @AccountMapId
  and new_accountnumber = @AccountNumber

  
 FETCH NEXT FROM My_cursor INTO @Accountid, @AccountName
END 
CLOSE My_cursor;
DEALLOCATE My_cursor;