USP_MKTSEGMENTLIST_FINDANDUPDATEDUPLICATES

Finds all duplicate records in a list segment with imported records based on the record source duplicate criteria and then flags each record found as a duplicate.

Parameters

Parameter Parameter Type Mode Description
@SEGMENTID uniqueidentifier IN

Definition

Copy


CREATE procedure dbo.[USP_MKTSEGMENTLIST_FINDANDUPDATEDUPLICATES]
(
  @SEGMENTID uniqueidentifier
)
as
  set nocount on;

  declare @SEGMENTLISTID uniqueidentifier;
  declare @MINIMUMDATAID uniqueidentifier;
  declare @MAXIMUMDATAID uniqueidentifier;
  declare @LISTQUERYVIEWCATALOGID uniqueidentifier;
  declare @DUPLICATEID uniqueidentifier;
  declare @CONSOLIDATEDQUERYVIEWCATALOGID uniqueidentifier;
  declare @QUERYVIEWNAME nvarchar(128);

  declare @FIELDNAME nvarchar(100);
  declare @FIELDLENGTH smallint;
  declare @TOTALFIELDLENGTH int = 0;
  declare @SQL nvarchar(max) = '';
  declare @DUPLICATEFIELDSSQL nvarchar(max) = '';

  declare @RECORDSOURCEID uniqueidentifier;
  declare @ISENCRYPTED bit;
  declare @GRANTKEYACCESS bit = 0;

  begin try
    select
      @SEGMENTLISTID = [MKTSEGMENTLIST].[ID],
      @MINIMUMDATAID = [MKTSEGMENTLIST].[MINIMUMDATAID],
      @MAXIMUMDATAID = [MKTSEGMENTLIST].[MAXIMUMDATAID],
      @LISTQUERYVIEWCATALOGID = [MKTSEGMENTLIST].[QUERYVIEWCATALOGID],
      @DUPLICATEID = [MKTDUPLICATE].[ID],
      @CONSOLIDATEDQUERYVIEWCATALOGID = [MKTCONSOLIDATEDQUERYVIEWSPEC].[CONSOLIDATEDQUERYVIEWCATALOGID],
      @QUERYVIEWNAME = [QUERYVIEWCATALOG].[OBJECTNAME],
      @RECORDSOURCEID = [MKTLIST].[RECORDSOURCEID]
    from dbo.[MKTSEGMENT]
    inner join dbo.[MKTSEGMENTLIST] on [MKTSEGMENTLIST].[ID] = [MKTSEGMENT].[CURRENTSEGMENTLISTID]
    inner join dbo.[MKTLIST] on [MKTLIST].[ID] = [MKTSEGMENTLIST].[LISTID]
    left join dbo.[MKTDUPLICATE] on [MKTDUPLICATE].[QUERYVIEWCATALOGID] = [MKTLIST].[RECORDSOURCEID]
    left join dbo.[MKTCONSOLIDATEDQUERYVIEWSPEC] on [MKTCONSOLIDATEDQUERYVIEWSPEC].[ID] = [MKTLIST].[RECORDSOURCEID]
    inner join dbo.[QUERYVIEWCATALOG] on [QUERYVIEWCATALOG].[ID] = isnull([MKTCONSOLIDATEDQUERYVIEWSPEC].[CONSOLIDATEDQUERYVIEWCATALOGID], [MKTLIST].[RECORDSOURCEID])
    where [MKTSEGMENT].[ID] = @SEGMENTID;

    --Only dedupe if duplicate criteria has been defined for this record source...

    if @DUPLICATEID is not null and exists(select top 1 1 from dbo.[MKTDUPLICATEFIELD] where [DUPLICATEID] = @DUPLICATEID) and dbo.[UFN_MKTSEGMENTLIST_DUPLICATEFIELDSEXIST](@SEGMENTLISTID) = 1
      begin
        --Reset all the duplicates for this list segment (NOTE: it is quicker to use the non-clustered index field SEGMENTLISTID in the 

        --where clause in this case because the index also includes the ISDUPLICATE field.  Do not change to use MIN and MAX IDs).

        update dbo.[MKTSEGMENTLISTDATA] set
          [ISDUPLICATE] = 0
        where [SEGMENTLISTID] = @SEGMENTLISTID
        and [ISDUPLICATE] = 1;

        --Create field SQL to use to determine duplicate records...

        declare DUPLICATECURSOR cursor local fast_forward for
          select
            [FIELDNAME],
            [FIELDLENGTH],
            dbo.[UFN_MKTSEGMENTLIST_ISFIELDENCRYPTED](@RECORDSOURCEID, [FIELDNAME])
          from dbo.[MKTDUPLICATEFIELD]
          where [DUPLICATEID] = @DUPLICATEID;

        open DUPLICATECURSOR;
        fetch next from DUPLICATECURSOR into @FIELDNAME, @FIELDLENGTH, @ISENCRYPTED;

        while (@@FETCH_STATUS = 0)
        begin
          if len(@DUPLICATEFIELDSSQL) > 0
            set @DUPLICATEFIELDSSQL = @DUPLICATEFIELDSSQL + ' + ';

          --Need to use ltrim() and rtrim() here to remove any leading/trailing spaces from the field values...

          if @ISENCRYPTED = 1
            set @GRANTKEYACCESS = 1;

          set @DUPLICATEFIELDSSQL = @DUPLICATEFIELDSSQL + 'isnull(left(ltrim(rtrim([L].[' + @FIELDNAME + '])), ' + cast(@FIELDLENGTH as nvarchar) + '), '''')';
          set @TOTALFIELDLENGTH += @FIELDLENGTH;

          fetch next from DUPLICATECURSOR into @FIELDNAME, @FIELDLENGTH, @ISENCRYPTED;
        end

        close DUPLICATECURSOR;
        deallocate DUPLICATECURSOR;

        --Find and mark all the duplicate records...

        if @GRANTKEYACCESS = 1
          set @SQL = 'exec dbo.[USP_GET_KEY_ACCESS];' + char(13) + char(13);

        --To improve matching performance of the update statement below, store the dupkey for all records in the housefile in a temp table first...

        set @SQL += 'create table #HOUSEFILE (' + char(13) +
                    '  [DUPKEY] nvarchar(' + cast(@TOTALFIELDLENGTH as nvarchar(10)) + ') collate database_default not null' + char(13) +
                    ');' + char(13) +
                    char(13) +
                    'insert into #HOUSEFILE ([DUPKEY])' + char(13) +
                    '  select (' + replace(@DUPLICATEFIELDSSQL, '[L].', '') + ')' + char(13) +
                    '  from dbo.[' + @QUERYVIEWNAME + ']';

        --If a consolidated query exists for this record source, then exclude the current list segment we are processing...

        if @CONSOLIDATEDQUERYVIEWCATALOGID is not null
          set @SQL += char(13) + '  where [SOURCEQUERYVIEWID] <> @LISTQUERYVIEWCATALOGID';

        set @SQL += ';' + char(13) +
                    char(13) +
                    'create nonclustered index [IX_HOUSEFILE_DUPKEY] on #HOUSEFILE ([DUPKEY]);' + char(13) +
                    char(13) +
                    'update dbo.[MKTSEGMENTLISTDATA]' + char(13) +
                    '  set [ISDUPLICATE] = 1' + char(13);

        if @MINIMUMDATAID is not null and @MAXIMUMDATAID is not null
          --Use the clustered index of sequential IDs...

          set @SQL += 'from dbo.[MKTSEGMENTLISTDATA] as [L]' + char(13) +
                      'left join #HOUSEFILE as [HOUSEFILE] on [HOUSEFILE].[DUPKEY] = (' + @DUPLICATEFIELDSSQL + ')' + char(13) +
                      'where [L].[ID] between @MINIMUMDATAID and @MAXIMUMDATAID' + char(13);
        else
          --Force an index seek operation by specifying an index hint, otherwise it will do a slower index scan...

          set @SQL += 'from dbo.[MKTSEGMENTLISTDATA] as [L] with (INDEX([IX_MKTSEGMENTLISTDATA_SEGMENTLISTID]))' + char(13) +
                      'left join #HOUSEFILE as [HOUSEFILE] on [HOUSEFILE].[DUPKEY] = (' + @DUPLICATEFIELDSSQL + ')' + char(13) +
                      'where [L].[SEGMENTLISTID] = @SEGMENTLISTID' + char(13);

        --Check if the dupkeys match or if the list member has given a gift in the past and been matched back by another mailing...

        set @SQL += 'and ([HOUSEFILE].[DUPKEY] is not null or exists(select * from dbo.[' + dbo.[UFN_MKTRECORDSOURCE_MAKEMATCHBACKTABLENAME](@RECORDSOURCEID) + '] where [ID] = [L].[ID])';

        if dbo.[UFN_MKTRECORDSOURCE_VALIDFORBBEC](@RECORDSOURCEID) = 1
          --If it is a BBEC record source, then also check if the list member ID is equal to a constituent ID...

          set @SQL += ' or exists(select * from dbo.[CONSTITUENT] where [ID] = [L].[ID])';

        set @SQL += ');' + char(13) +
                    char(13) +
                    'drop table #HOUSEFILE;';

        if @GRANTKEYACCESS = 1
          set @SQL += char(13) + char(13) + 'close symmetric key sym_BBInfinity;';

        if @MINIMUMDATAID is not null and @MAXIMUMDATAID is not null
          exec sp_executesql @SQL, N'@MINIMUMDATAID uniqueidentifier, @MAXIMUMDATAID uniqueidentifier, @LISTQUERYVIEWCATALOGID uniqueidentifier', @MINIMUMDATAID = @MINIMUMDATAID, @MAXIMUMDATAID = @MAXIMUMDATAID, @LISTQUERYVIEWCATALOGID = @LISTQUERYVIEWCATALOGID;
        else
          exec sp_executesql @SQL, N'@SEGMENTLISTID uniqueidentifier, @LISTQUERYVIEWCATALOGID uniqueidentifier', @SEGMENTLISTID = @SEGMENTLISTID, @LISTQUERYVIEWCATALOGID = @LISTQUERYVIEWCATALOGID;
      end
  end try

  begin catch
    exec dbo.[USP_RAISE_ERROR];
    return 1;
  end catch

  return 0;