USP_MKTSEGMENTATIONACTIVATE_UPDATEFINDERNUMBERS
Updates the marketing efforts finder numbers based on reservations and check digit logic.
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@SEGMENTATIONID | uniqueidentifier | IN | |
@CHANGEAGENTID | uniqueidentifier | IN |
Definition
Copy
CREATE procedure dbo.[USP_MKTSEGMENTATIONACTIVATE_UPDATEFINDERNUMBERS]
(
@SEGMENTATIONID uniqueidentifier,
@CHANGEAGENTID uniqueidentifier = null
)
as
set nocount on;
declare @MAILINGTYPECODE tinyint;
declare @FINDERTABLE nvarchar(128);
declare @DATATABLE nvarchar(128);
declare @SQL nvarchar(max);
declare @AUXILIARYIDFIELD nvarchar(17);
declare @CURRENTDATE datetime;
declare @VENDORID uniqueidentifier;
declare @MIN bigint;
declare @MAX bigint;
declare @ASSIGNED bigint;
declare @QUANTITY bigint;
declare @SEEDS integer;
declare @RESERVED bigint;
declare @OFFSET bigint;
declare @CHECKDIGIT bit;
declare @WIDTH tinyint;
declare @RANGEID uniqueidentifier;
declare @LOCKNAME nvarchar(255) = 'MKTUpdateFinderNumbers';
declare @LOCKRESULT int;
begin try
if @CHANGEAGENTID is null
exec dbo.[USP_CHANGEAGENT_GETORCREATECHANGEAGENT] @CHANGEAGENTID output;
set @CURRENTDATE = getdate();
select
@MAILINGTYPECODE = [MAILINGTYPECODE],
@FINDERTABLE = dbo.[UFN_MKTSEGMENTATIONACTIVATE_MAKEFINDERTABLENAME]([ID]),
@DATATABLE = dbo.[UFN_MKTSEGMENTATIONACTIVATE_MAKETABLENAME]([ID])
from dbo.[MKTSEGMENTATION]
where [ID] = @SEGMENTATIONID;
select
@CHECKDIGIT = [CHECKDIGIT],
@WIDTH = [FIXEDWIDTH]
from dbo.[MKTFINDERNUMBER];
set @AUXILIARYIDFIELD = case @MAILINGTYPECODE
when 1 then '[REVENUEID], '
when 2 then '[MEMBERSHIPID], '
when 3 then '[SPONSORSHIPID], '
when 5 then '[REVENUEID], '
else ''
end;
-- synch finder number work table, cached before calculation started, with newly-calculated data
set @SQL = 'merge dbo.[##' + @FINDERTABLE + '] as target' + char(13) +
'using (select [DATA].[DONORQUERYVIEWCATALOGID], ' + @AUXILIARYIDFIELD + '[DATA].[DONORID], [DATA].[SEGMENTID], [MKTSEGMENTATIONSEGMENT].[EXCLUDE]' + char(13) +
' from dbo.[' + @DATATABLE + '] as [DATA]' + char(13) +
' inner join dbo.[MKTSEGMENTATIONSEGMENT] on [MKTSEGMENTATIONSEGMENT].[ID] = [DATA].[SEGMENTID])' + char(13) +
' as source ([DONORQUERYVIEWCATALOGID], ' + @AUXILIARYIDFIELD + '[DONORID], [SEGMENTID], [EXCLUDE])' + char(13) +
'on (target.[DONORQUERYVIEWCATALOGID] = source.[DONORQUERYVIEWCATALOGID]' + char(13) +
' and ' + case @MAILINGTYPECODE
when 1 then 'target.[REVENUEID] = source.[REVENUEID]' + char(13) + ' and '
when 2 then 'target.[MEMBERSHIPID] = source.[MEMBERSHIPID]' + char(13) + ' and '
when 3 then 'target.[SPONSORSHIPID] = source.[SPONSORSHIPID]' + char(13) + ' and '
when 5 then 'target.[REVENUEID] = source.[REVENUEID]' + char(13) + ' and '
else ''
end +
'target.[DONORID] = source.[DONORID])' + char(13) +
'when not matched by source then' + char(13) +
' --Remove members no longer present in the data' + char(13) +
' delete' + char(13) +
'when matched and (target.[SEGMENTID] <> source.[SEGMENTID] or target.[EXCLUDE] <> source.[EXCLUDE]) then' + char(13) +
' --Make sure the segment ID for remaining members is current' + char(13) +
' update set [SEGMENTID] = source.[SEGMENTID], [EXCLUDE] = source.[EXCLUDE], [FINDERNUMBER] = case when target.[EXCLUDE] <> source.[EXCLUDE] then null else [FINDERNUMBER] end' + char(13) +
'when not matched then' + char(13) +
' --Insert any new members' + char(13) +
' insert ([SEGMENTID], [EXCLUDE], [FINDERNUMBER], [DONORQUERYVIEWCATALOGID], ' + @AUXILIARYIDFIELD + '[DONORID])' + char(13) +
' values (source.[SEGMENTID], source.[EXCLUDE], null, source.[DONORQUERYVIEWCATALOGID], ' +
case @MAILINGTYPECODE
when 1 then 'source.[REVENUEID], '
when 2 then 'source.[MEMBERSHIPID], '
when 3 then 'source.[SPONSORSHIPID], '
when 5 then 'source.[REVENUEID], '
else ''
end +
'source.[DONORID]);';
--print @SQL + char(13);
exec (@SQL);
if @CHECKDIGIT = 1
begin
-- convert to raw finder numbers (strip check digit)
set @SQL = 'update dbo.[##' + @FINDERTABLE + '] set [FINDERNUMBER] = [FINDERNUMBER] / 10 where [FINDERNUMBER] > 0;';
--print @SQL + char(13);
exec (@SQL);
end
--Create a nonclustered index on FINDERNUMBER
set @SQL = 'create nonclustered index [IX_' + @FINDERTABLE + '_FINDERNUMBER] on [dbo].[##' + @FINDERTABLE + '] ([FINDERNUMBER] asc) include ([SEGMENTID]) with (PAD_INDEX = off, SORT_IN_TEMPDB = on, DROP_EXISTING = off, IGNORE_DUP_KEY = off, ONLINE = off)';
--print @SQL + char(13);
exec (@SQL);
--Create a nonclustered index on ROWNUMBER
set @SQL = 'create nonclustered index [IX_' + @FINDERTABLE + '_ROWNUMBER] on [dbo].[##' + @FINDERTABLE + '] ([ROWNUMBER] asc) include ([FINDERNUMBER], [SEGMENTID]) with (PAD_INDEX = off, SORT_IN_TEMPDB = on, DROP_EXISTING = off, IGNORE_DUP_KEY = off, ONLINE = off)';
--print @SQL + char(13);
exec (@SQL);
--Grab an applock so the activate and segment counts process don't conflict with overlapping finder numbers.
--We need to get this lock before we start messing with finder number ranges and the MKTSEGMENTATIONFINDERNUMBER table.
exec @LOCKRESULT = sp_getapplock @Resource=@LOCKNAME, @LockMode='Exclusive', @LockOwner='Session', @LockTimeout=3600000;
if @LOCKRESULT < 0
raiserror('A failure or timeout occurred while requesting an app lock to update finder numbers for a marketing effort.', 13, 1);
-- work with reservations for vendor managed lists
declare VMLVENDORS cursor local fast_forward for
select
[L].[VENDORID],
sum(isnull([SSL].[EXCHANGEQUANTITY], [SL].[EXCHANGEQUANTITY]) + isnull([SSL].[RENTALQUANTITY], [SL].[RENTALQUANTITY])) as [QUANTITY]
from dbo.[MKTSEGMENTATIONSEGMENT] as [SS]
left outer join dbo.[MKTSEGMENTATIONSEGMENTLIST] as [SSL] on [SSL].[ID] = [SS].[ID]
inner join dbo.[MKTSEGMENT] as [S] on [S].[ID] = [SS].[SEGMENTID]
inner join dbo.[MKTSEGMENTLIST] as [SL] on [SL].[ID] = [S].[CURRENTSEGMENTLISTID]
inner join dbo.[MKTLIST] as [L] on [L].[ID] = [SL].[LISTID]
where [SS].[SEGMENTATIONID] = @SEGMENTATIONID and [SL].[TYPECODE] = 1
group by [L].[VENDORID];
open VMLVENDORS;
fetch next from VMLVENDORS into @VENDORID, @QUANTITY;
while (@@FETCH_STATUS = 0)
begin
if @QUANTITY > 0
begin
if exists (select top 1 1 from dbo.[MKTSEGMENTATIONFINDERNUMBER] where [SEGMENTATIONID] = @SEGMENTATIONID and [VENDORID] = @VENDORID)
begin
update dbo.[MKTSEGMENTATIONFINDERNUMBER] set
[INUSE] = 1,
[CHANGEDBYID] = @CHANGEAGENTID,
[DATECHANGED] = @CURRENTDATE
where [SEGMENTATIONID] = @SEGMENTATIONID and [VENDORID] = @VENDORID;
select @RESERVED = sum([MAX] - [MIN] + 1) from dbo.[MKTSEGMENTATIONFINDERNUMBER] where [SEGMENTATIONID] = @SEGMENTATIONID and [VENDORID] = @VENDORID;
set @QUANTITY = @QUANTITY - @RESERVED;
end
-- if there are vendor managed list segment members left over after taking into account all of the ranges set up for this vendor...
if @QUANTITY > 0
begin
select @MIN = max([MAX])
from (
select isnull(max([MAX]), 0) as [MAX] from dbo.[MKTSEGMENTATIONFINDERNUMBER]
union
select isnull(max([FINDERNUMBER]), 0) as [MAX] from dbo.[MKTFINDERNUMBER] where [FINDERNUMBER] > 0
) as [NEXT];
-- does the last range for this vendor in this mailing also represent the highest range in use at the moment?
select
@RANGEID = [ID]
from dbo.[MKTSEGMENTATIONFINDERNUMBER]
where [SEGMENTATIONID] = @SEGMENTATIONID
and [VENDORID] = @VENDORID
and [MAX] = @MIN;
if @RANGEID is null
begin
-- if not, add a new range
set @MIN = @MIN + 1;
set @MAX = @MIN + @QUANTITY - 1;
exec dbo.[USP_DATAFORMTEMPLATE_ADD_MKTSEGMENTATIONFINDERNUMBER] @VENDORID = @VENDORID, @SEGMENTATIONID = @SEGMENTATIONID, @MIN = @MIN, @MAX = @MAX, @ISRESERVED = 0, @INUSE = 1, @CHANGEAGENTID = @CHANGEAGENTID;
end
else
begin
-- if so, simply extend the existing range
select @MIN = [MIN], @MAX = [MAX] from dbo.[MKTSEGMENTATIONFINDERNUMBER] where [ID] = @RANGEID;
set @MAX = @MAX + @QUANTITY;
exec dbo.[USP_DATAFORMTEMPLATE_EDIT_MKTSEGMENTATIONFINDERNUMBER] @ID = @RANGEID, @CHANGEAGENTID = @CHANGEAGENTID, @VENDORID = @VENDORID, @MIN = @MIN, @MAX = @MAX;
end
end
end
fetch next from VMLVENDORS into @VENDORID, @QUANTITY;
end
close VMLVENDORS;
deallocate VMLVENDORS;
-- work with reservations for house file / imported lists
-- use up any available numbers in any existing ranges
declare RANGES cursor local fast_forward for
select [MIN], [MAX]
from dbo.[MKTSEGMENTATIONFINDERNUMBER]
where [SEGMENTATIONID] = @SEGMENTATIONID
and [VENDORID] is null
order by [MIN] asc;
open RANGES;
fetch next from RANGES into @MIN, @MAX;
while (@@FETCH_STATUS) = 0
begin
if @MAILINGTYPECODE = 2 -- memberships
set @SQL = 'select @ASSIGNED = count(distinct [FINDERNUMBER]) from dbo.[##' + @FINDERTABLE + '] where [FINDERNUMBER] > 0 and [FINDERNUMBER] between @MIN and @MAX';
else
set @SQL = 'select @ASSIGNED = count([FINDERNUMBER]) from dbo.[##' + @FINDERTABLE + '] where [FINDERNUMBER] > 0 and [FINDERNUMBER] between @MIN and @MAX';
exec sp_executesql @SQL, N'@ASSIGNED bigint output, @MIN bigint, @MAX bigint', @ASSIGNED = @ASSIGNED output, @MIN = @MIN, @MAX = @MAX;
if @ASSIGNED < (@MAX - @MIN + 1) -- there are finder numbers remaining to be used in this range
begin
-- assign ROWNUMBER to the rows, ensuring that rows without finder numbers get the lowest numbers
-- rows without finder numbers will have ROWNUMBER 1, 2, 3...
-- windowed functions like row_number() can only be used in select and order by clauses, so shenanigans are necessary
set @SQL = 'update dbo.[##' + @FINDERTABLE + '] set' + char(13) +
' [ROWNUMBER] = [N].[ROWNUMBER]' + char(13) +
'from dbo.[##' + @FINDERTABLE + '] as [WORK]' + char(13) +
'inner join (' + char(13) +
' select [F].[DONORQUERYVIEWCATALOGID], ' +
case when @MAILINGTYPECODE = 1 then '[F].[REVENUEID], ' else '' end +
case when @MAILINGTYPECODE = 2 then '[F].[MEMBERSHIPID], ' else '' end +
case when @MAILINGTYPECODE = 3 then '[F].[SPONSORSHIPID], ' else '' end +
case when @MAILINGTYPECODE = 5 then '[F].[REVENUEID], ' else '' end +
'[F].[DONORID], row_number() over (order by [F].[FINDERNUMBER], [F].[SEGMENTID]) as [ROWNUMBER]' + char(13) +
' from dbo.[##' + @FINDERTABLE + '] as [F]' + char(13) +
' where [F].[EXCLUDE] = 0 and [F].[FINDERNUMBER] is null' + char(13) +
') as [N] on ([N].[DONORQUERYVIEWCATALOGID] = [WORK].[DONORQUERYVIEWCATALOGID] and ' +
case when @MAILINGTYPECODE = 1 then '[N].[REVENUEID] = [WORK].[REVENUEID] and ' else '' end +
case when @MAILINGTYPECODE = 2 then '[N].[MEMBERSHIPID] = [WORK].[MEMBERSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 3 then '[N].[SPONSORSHIPID] = [WORK].[SPONSORSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 5 then '[N].[REVENUEID] = [WORK].[REVENUEID] and ' else '' end +
'[N].[DONORID] = [WORK].[DONORID])' + char(13) +
'where [WORK].[EXCLUDE] = 0 and [WORK].[FINDERNUMBER] is null;';
--print @SQL + char(13);
exec sp_executesql @SQL;
-- assign unassigned finder numbers in this range to rows that don't have them from the UFN_MKTCOMMON_NUMBERS function,
-- using ROWNUMBER as the join field
-- numbers from UFN_MKTCOMMON_NUMBERS that aren't used will get ROWNUMBER 1, 2, 3...
-- windowed functions like row_number() can only be used in select and order by clauses, so shenanigans are again necessary
set @SQL = 'update dbo.[##' + @FINDERTABLE + '] set' + char(13) +
' [FINDERNUMBER] = [AVAILABLE].[NUMBER]' + char(13) +
'from dbo.[##' + @FINDERTABLE + '] as [WORK]' + char(13) +
'inner join (' + char(13) +
' select [NUMBERS].[NUMBER], row_number() over (order by [NUMBERS].[NUMBER]) as [ROWNUMBER]' + char(13) +
' from dbo.[##' + @FINDERTABLE + '] as [F]' + char(13) +
' right outer join dbo.[UFN_MKTCOMMON_NUMBERS](@MIN, @MAX) as [NUMBERS] on [NUMBERS].[NUMBER] = [F].[FINDERNUMBER]' + char(13) +
' where [F].[FINDERNUMBER] is null' + char(13) +
') as [AVAILABLE] on [AVAILABLE].[ROWNUMBER] = [WORK].[ROWNUMBER]' + char(13) +
'where [WORK].[EXCLUDE] = 0 and [WORK].[FINDERNUMBER] is null;';
--print @SQL + char(13);
exec sp_executesql @SQL, N'@MIN bigint, @MAX bigint', @MIN = @MIN, @MAX = @MAX;
-- Assign finder numbers to constituents if they were imported in a segmented house file.
if dbo.[UFN_MKTCONSTITUENTFILEIMPORT_IMPORTTABLEEXISTS](@SEGMENTATIONID) = 1
begin
declare @SEGMENTEDHOUSEFILETABLE nvarchar(128) = dbo.[UFN_MKTCONSTITUENTFILEIMPORT_BUILDTABLENAME](@SEGMENTATIONID);
--If they import multiple files and import the same RECORDID multiple times with different findernumbers, then
--we need to make sure we are only working with the findernumbers from the latest import file.
set @SQL = 'with [RANKEDIMPORT] ([RECORDID], [FINDERNUMBER], [RANK]) as' + char(13) +
'(' + char(13) +
' select' + char(13) +
' [IMPORTFILE].[RECORDID],' + char(13) +
' [IMPORTFILE].[FINDERNUMBER]' + (case when @CHECKDIGIT = 1 then ' / 10' else '' end) + ',' + char(13) +
' row_number() over (partition by [IMPORTFILE].[RECORDID] order by [MKTCONSTITUENTFILEIMPORTPROCESS].[DATEADDED] desc) as [RANK]' + char(13) +
' from dbo.[' + @SEGMENTEDHOUSEFILETABLE + '] as [IMPORTFILE]' + char(13) +
' inner join dbo.[MKTCONSTITUENTFILEIMPORTPROCESS] on [MKTCONSTITUENTFILEIMPORTPROCESS].[ID] = [IMPORTFILE].[CONSTITUENTFILEIMPORTID]' + char(13) +
'),' + char(13) +
'[LATESTIMPORT] ([RECORDID], [FINDERNUMBER]) as' + char(13) +
'(' + char(13) +
' select' + char(13) +
' [RECORDID],' + char(13) +
' [FINDERNUMBER]' + char(13) +
' from [RANKEDIMPORT]' + char(13) +
' where [RANK] = 1' + char(13) +
')' + char(13) +
'update dbo.[##' + @FINDERTABLE + ']' + char(13) +
' set [FINDERNUMBER] = [LATESTIMPORT].[FINDERNUMBER]' + char(13) +
'from dbo.[##' + @FINDERTABLE + '] as [WORK]' + char(13) +
'inner join [LATESTIMPORT] on [LATESTIMPORT].[RECORDID] = [WORK].[DONORID]' + char(13) +
'where [LATESTIMPORT].[FINDERNUMBER] is not null' + char(13) +
'and [LATESTIMPORT].[FINDERNUMBER] between @MIN and @MAX;';
--print @SQL + char(13);
exec sp_executesql @SQL, N'@MIN bigint, @MAX bigint', @MIN = @MIN, @MAX = @MAX;
end
end
fetch next from RANGES into @MIN, @MAX;
end
close RANGES;
deallocate RANGES;
-- assign finder numbers to any members who remain, and create ranges for those numbers
set @SQL = 'select @QUANTITY = count(*)' + char(13) +
'from dbo.[##' + @FINDERTABLE + ']' + char(13) +
'where [FINDERNUMBER] is null and [EXCLUDE] = 0';
exec sp_executesql @SQL, N'@QUANTITY bigint output', @QUANTITY = @QUANTITY output;
if @QUANTITY > 0
begin
select @MIN = max([MAX]) -- not +1 because the first ROWNUMBER will be 1
from (
select isnull(max([MAX]), 0) as [MAX] from dbo.[MKTSEGMENTATIONFINDERNUMBER]
union
select isnull(max([FINDERNUMBER]), 0) as [MAX] from dbo.[MKTFINDERNUMBER] where [FINDERNUMBER] > 0
) as [NEXT];
set @SQL = 'update dbo.[##' + @FINDERTABLE + '] set' + char(13) +
' [FINDERNUMBER] = [N].[ROWNUMBER] + @MIN' + char(13) +
'from dbo.[##' + @FINDERTABLE + '] as [WORK]' + char(13) +
'inner join (' + char(13) +
' select [DONORQUERYVIEWCATALOGID], ' +
case when @MAILINGTYPECODE = 1 then '[REVENUEID], [SEGMENTID], ' else '' end +
case when @MAILINGTYPECODE = 2 then '[MEMBERSHIPID], ' else '' end +
case when @MAILINGTYPECODE = 3 then '[SPONSORSHIPID], ' else '' end +
case when @MAILINGTYPECODE = 5 then '[REVENUEID], [SEGMENTID], ' else '' end +
'[DONORID], row_number() over (order by [FINDERNUMBER]) as [ROWNUMBER]' + char(13) +
' from dbo.[##' + @FINDERTABLE + ']' + char(13) +
' where [EXCLUDE] = 0' + char(13) +
') as [N]' + char(13) +
'on ([N].[DONORQUERYVIEWCATALOGID] = [WORK].[DONORQUERYVIEWCATALOGID] and ' +
case when @MAILINGTYPECODE = 1 then '[N].[REVENUEID] = [WORK].[REVENUEID] and [N].[SEGMENTID] = [WORK].[SEGMENTID] and ' else '' end +
case when @MAILINGTYPECODE = 2 then '[N].[MEMBERSHIPID] = [WORK].[MEMBERSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 3 then '[N].[SPONSORSHIPID] = [WORK].[SPONSORSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 5 then '[N].[REVENUEID] = [WORK].[REVENUEID] and [N].[SEGMENTID] = [WORK].[SEGMENTID] and ' else '' end +
'[N].[DONORID] = [WORK].[DONORID])' + char(13) +
'where [WORK].[EXCLUDE] = 0 and [WORK].[FINDERNUMBER] is null;';
set @MAX = @MIN + @QUANTITY;
--print @SQL + char(13);
exec sp_executesql @SQL, N'@MIN bigint', @MIN = @MIN;
-- does the last range for this mailing also represent the highest range in use at the moment?
select
@RANGEID = [ID]
from dbo.[MKTSEGMENTATIONFINDERNUMBER]
where [SEGMENTATIONID] = @SEGMENTATIONID
and [VENDORID] is null
and [MAX] = @MIN;
if @RANGEID is null
begin
-- if not, add a new range
set @MIN = @MIN + 1;
exec dbo.[USP_DATAFORMTEMPLATE_ADD_MKTSEGMENTATIONFINDERNUMBER] @SEGMENTATIONID = @SEGMENTATIONID, @VENDORID = null, @MIN = @MIN, @MAX = @MAX, @ISRESERVED = 0, @INUSE = 1, @CHANGEAGENTID = @CHANGEAGENTID;
end
else
begin
-- if so, simply extend the existing range
select @MIN = [MIN] from dbo.[MKTSEGMENTATIONFINDERNUMBER] where [ID] = @RANGEID;
exec dbo.[USP_DATAFORMTEMPLATE_EDIT_MKTSEGMENTATIONFINDERNUMBER] @ID = @RANGEID, @CHANGEAGENTID = @CHANGEAGENTID, @VENDORID = null, @MIN = @MIN, @MAX = @MAX;
end
end
-- deal with seeds
set @SEEDS = dbo.[UFN_MKTSEGMENTATIONSEED_GETSEEDCOUNT](@SEGMENTATIONID);
if @SEEDS > 0
begin
select
@QUANTITY = sum(dbo.[UFN_MKTSEGMENTATIONSEGMENT_GETCACHEDOFFERCOUNT]([SS].[ID]))
from dbo.[MKTSEGMENTATIONSEGMENT] as [SS]
inner join dbo.[MKTSEGMENT] as [S] on [S].[ID] = [SS].[SEGMENTID]
left outer join dbo.[MKTSEGMENTLIST] as [SL] on [SL].[ID] = [S].[CURRENTSEGMENTLISTID]
where [SS].[SEGMENTATIONID] = @SEGMENTATIONID and [SS].[EXCLUDE] = 0 and ([SL].[TYPECODE] is null or [SL].[TYPECODE] <> 1)
select
@RESERVED = sum(isnull([FN].[MAX] - [FN].[MIN] + 1, 0))
from dbo.[MKTSEGMENTATIONFINDERNUMBER] as [FN]
where [FN].[SEGMENTATIONID] = @SEGMENTATIONID
and [FN].[VENDORID] is null;
if @RESERVED < (@QUANTITY + @SEEDS)
begin
select @MIN = max([MAX]) -- not +1 because the first ROWNUMBER will be 1
from (
select isnull(max([MAX]), 0) as [MAX] from dbo.[MKTSEGMENTATIONFINDERNUMBER]
union
select isnull(max([FINDERNUMBER]), 0) as [MAX] from dbo.[MKTFINDERNUMBER] where [FINDERNUMBER] > 0
) as [NEXT];
set @MAX = @MIN + ((@QUANTITY + @SEEDS) - @RESERVED);
select
@RANGEID = [ID]
from dbo.[MKTSEGMENTATIONFINDERNUMBER]
where [SEGMENTATIONID] = @SEGMENTATIONID
and [VENDORID] is null
and [MAX] = @MIN;
if @RANGEID is null
begin
-- if not, add a new range
set @MIN = @MIN + 1;
exec dbo.[USP_DATAFORMTEMPLATE_ADD_MKTSEGMENTATIONFINDERNUMBER] @SEGMENTATIONID = @SEGMENTATIONID, @VENDORID = null, @MIN = @MIN, @MAX = @MAX, @ISRESERVED = 0, @INUSE = 1, @CHANGEAGENTID = @CHANGEAGENTID;
end
else
begin
-- if so, simply extend the existing range
select @MIN = [MIN] from dbo.[MKTSEGMENTATIONFINDERNUMBER] where [ID] = @RANGEID;
exec dbo.[USP_DATAFORMTEMPLATE_EDIT_MKTSEGMENTATIONFINDERNUMBER] @ID = @RANGEID, @CHANGEAGENTID = @CHANGEAGENTID, @VENDORID = null, @MIN = @MIN, @MAX = @MAX;
end
end
end
-- update the reservations with the width and check digit information at the time of activation
update dbo.[MKTSEGMENTATIONFINDERNUMBER] set
[CHECKDIGIT] = @CHECKDIGIT,
[FIXEDWIDTH] = @WIDTH,
[CHANGEDBYID] = @CHANGEAGENTID,
[DATECHANGED] = @CURRENTDATE
where [SEGMENTATIONID] = @SEGMENTATIONID;
--Release the applock for finder numbers...
if @LOCKRESULT is not null and @LOCKRESULT >= 0
exec sp_releaseapplock @Resource=@LOCKNAME, @LockOwner='Session';
set @LOCKRESULT = null;
if @CHECKDIGIT = 1
begin
--Drop the two indexes first since we don't need them anymore, and it will save it from having to update the indexes also when we add back the check-digit below...
--Drop the index on ROWNUMBER...
set @SQL = 'drop index [IX_' + @FINDERTABLE + '_ROWNUMBER] on [dbo].[##' + @FINDERTABLE + '];';
--print @SQL + char(13);
exec (@SQL);
--Drop the index on FINDERNUMBER...
set @SQL = 'drop index [IX_' + @FINDERTABLE + '_FINDERNUMBER] on [dbo].[##' + @FINDERTABLE + '];';
--print @SQL + char(13);
exec (@SQL);
end
set @SQL = 'select @QUANTITY = count(*)' + char(13) +
'from dbo.[##' + @FINDERTABLE + ']' + char(13) +
'where [FINDERNUMBER] is null and [EXCLUDE] = 1';
exec sp_executesql @SQL, N'@QUANTITY bigint output', @QUANTITY = @QUANTITY output;
if @QUANTITY > 0
begin
set @SQL = 'select @OFFSET = isnull(max(abs([FINDERNUMBER])), 0)' + char(13) +
'from dbo.[##' + @FINDERTABLE + ']' + char(13) +
'where [EXCLUDE] = 1 and [FINDERNUMBER] is not null';
exec sp_executesql @SQL, N'@OFFSET bigint output', @OFFSET = @OFFSET output;
-- assign fake, negative finder numbers to excluded members
set @SQL = 'update dbo.[##' + @FINDERTABLE + '] set' + char(13) +
' [FINDERNUMBER] = -1 * ([N].[ROWNUMBER] + @OFFSET)' + char(13) +
'from dbo.[##' + @FINDERTABLE + '] as [WORK]' + char(13) +
'inner join (' + char(13) +
' select [DONORQUERYVIEWCATALOGID], ' +
case when @MAILINGTYPECODE = 1 then '[REVENUEID], [SEGMENTID], ' else '' end +
case when @MAILINGTYPECODE = 2 then '[MEMBERSHIPID], ' else '' end +
case when @MAILINGTYPECODE = 3 then '[SPONSORSHIPID], ' else '' end +
case when @MAILINGTYPECODE = 5 then '[REVENUEID], [SEGMENTID], ' else '' end +
'[DONORID], row_number() over (order by [FINDERNUMBER]) as [ROWNUMBER]' + char(13) +
' from dbo.[##' + @FINDERTABLE + ']' + char(13) +
' where [EXCLUDE] = 1 and [FINDERNUMBER] is null' + char(13) +
') as [N]' + char(13) +
'on ([N].[DONORQUERYVIEWCATALOGID] = [WORK].[DONORQUERYVIEWCATALOGID] and ' +
case when @MAILINGTYPECODE = 1 then '[N].[REVENUEID] = [WORK].[REVENUEID] and [N].[SEGMENTID] = [WORK].[SEGMENTID] and ' else '' end +
case when @MAILINGTYPECODE = 2 then '[N].[MEMBERSHIPID] = [WORK].[MEMBERSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 3 then '[N].[SPONSORSHIPID] = [WORK].[SPONSORSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 5 then '[N].[REVENUEID] = [WORK].[REVENUEID] and [N].[SEGMENTID] = [WORK].[SEGMENTID] and ' else '' end +
'[N].[DONORID] = [WORK].[DONORID])' + char(13) +
'where [WORK].[EXCLUDE] = 1 and [WORK].[FINDERNUMBER] is null;';
exec sp_executesql @SQL, N'@OFFSET bigint', @OFFSET = @OFFSET;
end
-- transfer the finder numbers back into the data table (and add back the check digit if necessary)...
set @SQL = 'update dbo.[' + @DATATABLE + '] set ' + char(13) +
' [FINDERNUMBER] = ' + case when @CHECKDIGIT = 1 then 'case when [WORK].[FINDERNUMBER] > 0 then dbo.[UFN_MKTFINDERNUMBER_CHECKDIGIT_MOD10]([WORK].[FINDERNUMBER]) else [WORK].[FINDERNUMBER] end' else '[WORK].[FINDERNUMBER]' end + char(13) +
'from dbo.[' + @DATATABLE + '] as [DATA]' + char(13) +
'inner join dbo.[##' + @FINDERTABLE + '] as [WORK] on (' +
'[WORK].[DONORQUERYVIEWCATALOGID] = [DATA].[DONORQUERYVIEWCATALOGID] and ' +
case when @MAILINGTYPECODE = 1 then '[WORK].[REVENUEID] = [DATA].[REVENUEID] and [WORK].[SEGMENTID] = [DATA].[SEGMENTID] and ' else '' end +
case when @MAILINGTYPECODE = 2 then '[WORK].[MEMBERSHIPID] = [DATA].[MEMBERSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 3 then '[WORK].[SPONSORSHIPID] = [DATA].[SPONSORSHIPID] and ' else '' end +
case when @MAILINGTYPECODE = 5 then '[WORK].[REVENUEID] = [DATA].[REVENUEID] and [WORK].[SEGMENTID] = [DATA].[SEGMENTID] and ' else '' end +
'[WORK].[DONORID] = [DATA].[DONORID])'
--print @SQL + char(13);
exec (@SQL);
-- drop finder number work table
set @SQL = 'drop table dbo.[##' + @FINDERTABLE + '];';
--print @SQL + char(13);
exec (@SQL);
-- make finder number column not null
set @SQL = 'alter table dbo.[' + @DATATABLE + '] alter column [FINDERNUMBER] bigint not null;';
--print @SQL + char(13);
exec (@SQL);
-- add back finder number unique index
set @SQL = 'create unique nonclustered index [UIX_' + @DATATABLE + '_FINDERNUMBER] on dbo.[' + @DATATABLE + '] ([FINDERNUMBER] asc) with (PAD_INDEX = off, SORT_IN_TEMPDB = on, DROP_EXISTING = off, IGNORE_DUP_KEY = off, ONLINE = off, FILLFACTOR = 100' + (case when serverproperty('engineedition') = 3 then ', DATA_COMPRESSION = PAGE' else '' end) + ') on [IDXGROUP]';
--print @SQL + char(13);
exec (@SQL);
end try
begin catch
exec dbo.[USP_RAISE_ERROR];
--Release the applock for finder numbers if an error occurs...
if @LOCKRESULT is not null and @LOCKRESULT >= 0
exec sp_releaseapplock @Resource=@LOCKNAME, @LockOwner='Session';
set @LOCKRESULT = null;
return 1;
end catch
return 0;