【问题标题】:SQL proc to calculate check digit for 7 and 12 digit upcSQL proc 计算 7 位和 12 位 upc 的校验位
【发布时间】:2014-01-14 23:55:54
【问题描述】:

我不得不再次在互联网上搜索这段代码,所以我想我会把它放在这里,这样下次我可以更快地找到它,希望你也能更快地找到它:)

【问题讨论】:

    标签: sql tsql barcode checksum


    【解决方案1】:

    检查这个。 下面的代码可以检查所有 GTIN 中的数字(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
    

    【讨论】:

      【解决方案2】:
      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
      

      【讨论】:

        【解决方案3】:

        这里还有一个 MySQL 实现。 请注意,它需要 13 位 UPC/EAN13 作为输入,因此您应该根据需要使用 LPAD 输入。

        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 ;
        

        【讨论】:

          【解决方案4】:

          这是我在 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;
          

          【讨论】:

            【解决方案5】:

            计算最后一位数。

            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;
            

            【讨论】:

              【解决方案6】:
              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
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多