【发布时间】:2014-01-14 23:55:54
【问题描述】:
我不得不再次在互联网上搜索这段代码,所以我想我会把它放在这里,这样下次我可以更快地找到它,希望你也能更快地找到它:)
【问题讨论】:
我不得不再次在互联网上搜索这段代码,所以我想我会把它放在这里,这样下次我可以更快地找到它,希望你也能更快地找到它:)
【问题讨论】:
检查这个。 下面的代码可以检查所有 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
【讨论】:
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
【讨论】:
这里还有一个 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 ;
【讨论】:
这是我在 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;
【讨论】:
计算最后一位数。
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
【讨论】: