UFN_MKTSOURCECODEPARTDEFINITIONVALUES_GETIDFROMCODE

Returns the value ID of a source code part if it is valid for the specified source code layout.

Return

Return Type
uniqueidentifier

Parameters

Parameter Parameter Type Mode Description
@SOURCECODEID uniqueidentifier IN
@CODE nvarchar(10) IN
@ITEMTYPECODE tinyint IN
@SOURCECODEPARTDEFINITIONID uniqueidentifier IN

Definition

Copy


CREATE function dbo.[UFN_MKTSOURCECODEPARTDEFINITIONVALUES_GETIDFROMCODE]
(
  @SOURCECODEID uniqueidentifier = null,
  @CODE nvarchar(10),
  @ITEMTYPECODE tinyint,
  @SOURCECODEPARTDEFINITIONID uniqueidentifier = null   /* Required only when @ITEMTYPECODE = 5 (user-defined). */
)
returns uniqueidentifier
as
begin
  declare @RETURNID uniqueidentifier;
  declare @CODEVALUEID uniqueidentifier;
  declare @VALID bit = 0;
  declare @LENGTH tinyint = len(@CODE);
  declare @FORMAT nvarchar(10);
  declare @CODECHAR char;
  declare @FORMATCHAR char;
  declare @POS integer;
  declare @CODEMATCHES bit;

  --Set the source code part definition ID if not already set.

  if @SOURCECODEPARTDEFINITIONID is null and @ITEMTYPECODE <> 5
    begin
      select
        @SOURCECODEPARTDEFINITIONID = [ID]
      from dbo.[MKTSOURCECODEPARTDEFINITION]
      where [ITEMTYPECODE] = @ITEMTYPECODE;
    end

  --Loop through each value for the part and make sure we have a valid value.  If the code part contains a mix of literals and wildcards,

  --then we start matching with the most restrictive to the least restrictive.  Count up the number of literals, #'s, @?s, and ?'s.  Then

  --sort by the number of literals, #'s, @?s, ?'s, rank, and alpha.

  declare VALUECURSOR cursor local fast_forward for
    with [TEMP0] ([ID], [FORMAT], [NUMLITERALS], [NUMDIGITS], [NUMALPHAS], [NUMANYCHARS]) as
    (
      select distinct
        [MKTSOURCECODEPARTDEFINITIONVALUES].[ID],
        [MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT],
        len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - ((len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - len(replace([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT], '#', ''))) + (len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - len(replace([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT], '@', ''))) + (len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - len(replace([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT], '?', '')))) as [NUMLITERALS],
        len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - len(replace([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT], '#', '')) as [NUMDIGITS],
        len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - len(replace([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT], '@', '')) as [NUMALPHAS],
        len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) - len(replace([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT], '?', '')) as [NUMANYCHARS]
      from dbo.[MKTSOURCECODEPARTDEFINITION]
      inner join dbo.[MKTSOURCECODEPARTDEFINITIONVALUES] on [MKTSOURCECODEPARTDEFINITIONVALUES].[MKTSOURCECODEPARTDEFINITIONID] = [MKTSOURCECODEPARTDEFINITION].[ID]
      left join dbo.[MKTSOURCECODEVALIDPARTVALUES] on [MKTSOURCECODEVALIDPARTVALUES].[MKTSOURCECODEPARTDEFINITIONVALUESID] = [MKTSOURCECODEPARTDEFINITIONVALUES].[ID]
      left join dbo.[MKTSOURCECODEITEM] on [MKTSOURCECODEITEM].[ID] = [MKTSOURCECODEVALIDPARTVALUES].[MKTSOURCECODEITEMID]
      where (@SOURCECODEID is null or [MKTSOURCECODEITEM].[SOURCECODEID] = @SOURCECODEID or not exists(select 1 from dbo.[MKTSOURCECODEITEM] as [SCI] inner join dbo.[MKTSOURCECODEPARTDEFINITION] as [SCPD] on [SCPD].[ID] = [SCI].[MKTSOURCECODEPARTDEFINITIONID] where [SCI].[SOURCECODEID] = @SOURCECODEID and [SCPD].[ITEMTYPECODE] = @ITEMTYPECODE))
      and (@SOURCECODEPARTDEFINITIONID is null or [MKTSOURCECODEPARTDEFINITION].[ID] = @SOURCECODEPARTDEFINITIONID)
      and [MKTSOURCECODEPARTDEFINITION].[ITEMTYPECODE] = @ITEMTYPECODE
      and len([MKTSOURCECODEPARTDEFINITIONVALUES].[FORMAT]) = @LENGTH
    ),
    [TEMP1] ([ID], [FORMAT], [NUMLITERALS], [NUMDIGITS], [NUMALPHAS], [NUMANYCHARS], [C1], [C2], [C3], [C4], [C5], [C6], [C7], [C8], [C9], [C0]) as
    (
      --Split up the format string so we can rank the special format characters (#, @, ?) to get the correct sorting...

      select [ID], [FORMAT], [NUMLITERALS], [NUMDIGITS], [NUMALPHAS], [NUMANYCHARS],
        substring([FORMAT], 1, 1),
        substring([FORMAT], 2, 1),
      substring([FORMAT], 3, 1),
        substring([FORMAT], 4, 1),
        substring([FORMAT], 5, 1),
        substring([FORMAT], 6, 1),
        substring([FORMAT], 7, 1),
        substring([FORMAT], 8, 1),
        substring([FORMAT], 9, 1),
        substring([FORMAT], 10, 1)
      from [TEMP0]
    ),
    [TEMP2] ([ID], [FORMAT], [NUMLITERALS], [NUMDIGITS], [NUMALPHAS], [NUMANYCHARS], [R1], [R2], [R3], [R4], [R5], [R6], [R7], [R8], [R9], [R0]) as
    (
      --Rank each character so the special characters sort correctly...

      select [ID], [FORMAT], [NUMLITERALS], [NUMDIGITS], [NUMALPHAS], [NUMANYCHARS],
        (case [C1] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C2] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C3] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C4] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C5] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C6] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C7] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C8] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C9] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end),
        (case [C0] when '#' then 2 when '@' then 3 when '?' then 4 else 1 end)
      from [TEMP1]
    )
    select
      [ID],
      [FORMAT]
    from [TEMP2]
    order by
      [NUMLITERALS] desc, [NUMDIGITS] desc, [NUMALPHAS] desc, [NUMANYCHARS] desc,
      [R1] asc, [R2] asc, [R3] asc, [R4] asc, [R5] asc, [R6] asc, [R7] asc, [R8] asc, [R9] asc, [R0] asc,
      [FORMAT] asc;

  open VALUECURSOR;
  fetch next from VALUECURSOR into @CODEVALUEID, @FORMAT;

  while (@@FETCH_STATUS = 0 and @VALID = 0)
  begin
    --Parse each code and format to see if code conforms to the source code format...

    set @CODEMATCHES = 1;
    set @POS = 1;
    set @CODECHAR = substring(@CODE, @POS, 1);
    set @FORMATCHAR = substring(@FORMAT, @POS, 1);

    while (@POS <= @LENGTH and @CODEMATCHES = 1)
    begin
      --Compare code and format characters...

      if @FORMATCHAR = '#' -- number

        --If code character is numeric and format is # then code matches...

        set @CODEMATCHES = (case when patindex('[0-9]', @CODECHAR) > 0 then 1 else 0 end);
      else if @FORMATCHAR = '@' -- alpha

        --If code character is not numeric and format is @ then code matches...

        set @CODEMATCHES = (case when patindex('[A-Za-z]', @CODECHAR) > 0 then 1 else 0 end);
      else if @FORMATCHAR = '?' -- number or alpha character

        set @CODEMATCHES = (case when patindex('[0-9A-Za-z]', @CODECHAR) > 0 then 1 else 0 end);
      else  -- literal

        --Format character is a literal character, so code only matches if it is equal to the format character...

        set @CODEMATCHES = (case when @CODECHAR = @FORMATCHAR then 1 else 0 end);

      set @POS += 1;
      set @CODECHAR = substring(@CODE, @POS, 1);
      set @FORMATCHAR = substring(@FORMAT, @POS, 1);
    end

    set @VALID = @CODEMATCHES;
    set @RETURNID = @CODEVALUEID;

    fetch next from VALUECURSOR into @CODEVALUEID, @FORMAT;
  end

  close VALUECURSOR;
  deallocate VALUECURSOR;

  if @VALID = 0
    set @RETURNID = null;

  return @RETURNID;
end