문제

I just had to scour the internet for this code yet again so I figured I would put it here so I can find it a little faster the next time and hopefully you found it a little faster too :)

도움이 되었습니까?

해결책

Check this. The code below can check digit in all GTIN's (EAN8, EAN13, EAN14, UPC/A, UPC/E)

CREATE FUNCTION [dbo].[check_digit]
(
    @GTIN VARCHAR(14)
)
RETURNS TINYINT
AS
BEGIN
    DECLARE @Index TINYINT,
            @Multiplier TINYINT,
            @Sum TINYINT,
            @checksum TINYINT,
            @result TINYINT,
            @GTIN_strip VARCHAR(13)

    SELECT  @GTIN_strip = SUBSTRING(@GTIN,1,LEN(@GTIN)-1);

    SELECT  @Index = LEN(@GTIN_strip),
            @Multiplier = 3,
            @Sum = 0

    WHILE @Index > 0
        SELECT  @Sum = @Sum + @Multiplier * CAST(SUBSTRING(@GTIN_strip, @Index, 1) AS TINYINT),
            @Multiplier = 4 - @Multiplier,
            @Index = @Index - 1

    SELECT @checksum = CASE @Sum % 10
            WHEN 0 THEN '0'
            ELSE CAST(10 - @Sum % 10 AS CHAR(1))
        END


    IF (SUBSTRING(@GTIN,LEN(@GTIN),1) = @checksum)
        RETURN 1; /*true*/
        RETURN 0; /*false*/
END

다른 팁

CREATE FUNCTION [dbo].[fn_EAN13CheckDigit] (@Barcode nvarchar(12)) 
RETURNS nvarchar(13) 
AS 
BEGIN 
    DECLARE @SUM int , @COUNTER int, @RETURN varchar(13), @Val1 int, @Val2 int 
    SET @COUNTER = 1 SET @SUM = 0 

    WHILE @Counter < 13 
    BEGIN 
        SET @VAL1 = SUBSTRING(@Barcode,@counter,1) * 1 
        SET @VAL2 = SUBSTRING(@Barcode,@counter + 1,1) * 3 
        SET @SUM = @VAL1 + @SUM 
        SET @SUM = @VAL2 + @SUM 
        SET @Counter = @Counter + 2; 
    END 
    SET @SUM=(10-(@SUM%10))%10

    SET @Return = @BARCODE + CONVERT(varchar,((@SUM))) 
    RETURN @Return 
END

And here's a MySQL implementation as well. Note it requires a 13 digit UPC/EAN13 as input, so you should LPAD your input as required.

drop function if exists barcodify;
delimiter //
 at the last digit.
create function barcodify(upc varchar(15))
    returns varchar(15)
    sql security invoker
begin
    declare i, r, odd, even,result int;

    set odd=0;
    set even =0;
    set i = length(upc);

    while i > 0 do
        set r = substring(upc, i, 1) ;
        if(i % 2 >0) then set odd = odd + r;
        else set even = even + r;
        end if;
        set i = i - 1;
    end while;
    set result = (3*odd)+even;

    if result % 10 =0 then return 0;
    else return (10 - (result %10));
    end if;
end //

delimiter ;

Here's my implementation of a function in Oracle.

CREATE OR REPLACE FUNCTION GenerateCheckDigit(pUPC IN VARCHAR2) RETURN INT
  IS
  vCheckDigit INT;
  BEGIN

    WITH barcodeData AS 
    (
      SELECT pUPC barcode FROM dual
    )
    SELECT       
      10-REPLACE(MOD(SUM(SUBSTR(barcode, -LEVEL, 1) * DECODE(MOD(LEVEL-1, 2), 1, 1, 3)),10),0,10) INTO vCheckDigit
      FROM barcodeData 
    CONNECT BY LEVEL <= LENGTH(barcode);

    RETURN vCheckDigit;

  END;

To calculate the last digit.

https://segovoni.medium.com/sql-server-function-to-calculate-gs1-barcode-check-digit-d55b478ff645

CREATE FUNCTION dbo.udf_GetGS1EAN13CheckDigit
(
  @ACode AS VARCHAR(12)
) 
RETURNS SMALLINT
AS BEGIN
  /*
    Author: Sergio Govoni
    Notes: Calculate the check-digit of a GS1 EAN13 code
    Version: 1.0
  */
  DECLARE
    @tmpCode AS VARCHAR(12)
    ,@tmpMulSup AS VARCHAR(8000)
    ,@tmp AS VARCHAR(8000)
    ,@i AS INT
    ,@j AS INT
    ,@z AS INT
    ,@SumDEven AS INT
    ,@SumDOdd AS INT
    ,@List AS VARCHAR(8000)
    ,@tmpList AS VARCHAR(8000)
    ,@CheckSum AS SMALLINT
 
  SET @SumDEven = 0
  SET @SumDOdd = 0
  SET @List = ''
  SET @tmpList = ''
  SET @tmp = ''
  SET @tmpCode = @ACode
 
  /* 0. List builder */
  SET @j = LEN(@tmpCode) + 1
  SET @i = 1
  WHILE (@i <= LEN(@tmpCode)) BEGIN SET @List = @List + '|' + LTRIM(RTRIM(STR(@j))) + ';' + SUBSTRING(@tmpCode, @i, 1) SET @j = (@j - 1) SET @i = (@i + 1) END /* 1. Add up the digits in even position */ SET @i = 1 SET @tmpList = @List WHILE (CHARINDEX('|', @tmpList) > 0)
  BEGIN
    SET @j = CHARINDEX('|', @tmpList)
    SET @z = CHARINDEX(';', @tmpList)
    IF (CAST(SUBSTRING(@tmpList, (@j + 1), (@z - (@j + 1))) AS INTEGER) % 2) = 0
    BEGIN
      SET @SumDEven = @SumDEven + CAST(SUBSTRING(@tmpList, (@z + 1), 1) AS INTEGER)
    END
    SET @tmpList = SUBSTRING(@tmpList, (@z + 2), LEN(@tmpList))
  END
 
  /* 2. Multiply the result of the previous step (the first step) to 3 (three) */
  SET @SumDEven = (@SumDEven * 3)
 
  /* 3. Add up the digits in the odd positions */
  SET @i = 1
  SET @tmpList = @List
  WHILE (CHARINDEX('|', @tmpList) > 0)
  BEGIN
    SET @j = CHARINDEX('|', @tmpList)
    SET @z = CHARINDEX(';', @tmpList)
    IF (CAST(SUBSTRING(@tmpList, (@j + 1), (@z - (@j + 1))) AS INTEGER) % 2) <> 0
    BEGIN
      SET @SumDOdd = @SumDOdd + CAST(SUBSTRING(@tmpList, (@z + 1), 1) AS INTEGER)
    END
    SET @tmpList = SUBSTRING(@tmpList, (@z + 2), LEN(@tmpList))
  END
 
  /* 4. Add up the results obtained in steps two and three */
  SET @CheckSum = (@SumDEven + @SumDOdd)
 
 /* 5. Subtract the upper multiple of 10 from the result obtained in step four */
  IF ((@CheckSum % 10) = 0)
  BEGIN
    /* If the result of the four step is a multiple of Ten (10), like
       Twenty, Thirty, Forty and so on,
       the check-digit will be equal to zero, otherwise the check-digit will be
       the result of the fifth step
    */
    SET @CheckSum = 0
  END
  ELSE BEGIN
    SET @tmpMulSup = LTRIM(RTRIM(STR(@CheckSum)))
    
    SET @i = 0
    WHILE @i <= (LEN(@tmpMulSup) - 1)
    BEGIN
      SET @tmp = @tmp + SUBSTRING(@tmpMulSup, @i, 1)
      IF (@i = LEN(@tmpMulSup) - 1)
      BEGIN
        SET @tmp = LTRIM(RTRIM(STR(CAST(@tmp AS INTEGER) + 1)))
        SET @tmp = @tmp + '0'
      END
      SET @i = (@i + 1)
    END
    SET @CheckSum = CAST(@tmp AS INTEGER) - @CheckSum
  END
  RETURN @CheckSum
END;
CREATE  FUNCTION sfn_ean_chkdigit(@barcode varchar(20))
RETURNS CHAR(1)
AS
BEGIN
    DECLARE @chk_digit int, @chk int
    DECLARE @num TABLE (num int)

    IF LEN(@barcode) NOT IN (7, 12) RETURN NULL

    INSERT INTO @num 
    SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL  
    SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL 
    SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12

    SELECT @chk_digit = SUM(CONVERT(int, SUBSTRING(@barcode, LEN(@barcode) - num + 1, 1)) * CASE WHEN num % 2 = 1 THEN 3 ELSE 1 END)
    FROM   @num
    WHERE  num    <= LEN(@barcode)

    SELECT @chk_digit = (10 - (@chk_digit % 10)) % 10

    RETURN  CHAR(ASCII('0') + @chk_digit)
END
select lpad('123456789012',12,'0') || ( (r+1)*10 - soma )%10
  from (select       sum(v::int * case when i%2=0 then 3 else 1 end)       soma, 
               round(sum(v::int * case when i%2=0 then 3 else 1 end)/10.0) r 
          from unnest(string_to_array(lpad('123456789012',12,'0'),null)) with ordinality d(v,i)
       ) a
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top