在 SQL Server 中计算 GS1 校验位的标量值函数

Posted

技术标签:

【中文标题】在 SQL Server 中计算 GS1 校验位的标量值函数【英文标题】:Scalar Valued Function to calculate a GS1 check digit in SQL Server 【发布时间】:2020-03-25 20:15:37 【问题描述】:

我需要在 SQL Server 中从 13 位 varchar 计算 GTIN-14 (ITF-14) 校验位,并返回 14 位计算数字(作为 varchar)。

我发现this post 创建了一个表值函数,但为了在我的应用程序中工作,我需要一个标量值函数。

任何帮助表示赞赏。

CREATE FUNCTION [GtinCheckDigit] 
    (@Input VARCHAR(17))
RETURNS TABLE 
WITH SCHEMABINDING 
AS
    RETURN 
        WITH [ReverseInput](S) AS 
        (
            SELECT REVERSE(@Input)
        ), [CharCount](N) AS 
        (
            SELECT n 
            FROM 
                (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17)) a(n)
        ), [CharPos](N,S) AS 
        (
            SELECT TOP (LEN(@Input)) 
                [CharCount].N, SUBSTRING([ReverseInput].S, [CharCount].N, 1)
            FROM 
                [CharCount], [ReverseInput]
        ), [Multiplier](N) AS 
        (
            SELECT 
                (S * CASE WHEN (N%2) = 0 THEN 1 ELSE 3 END)
            FROM 
                [CharPos]
        ), [Checksum](N) AS 
        (
            SELECT 
                CASE WHEN (SUM(N) % 10) > 0 THEN (10 - (SUM(N) % 10)) ELSE 0 END
            FROM 
                [Multiplier]
        )
        SELECT @Input + CAST(N AS VARCHAR) AS [Output] 
        FROM [Checksum];

【问题讨论】:

【参考方案1】:

我不知道这是否是最好的方法,但这里有一个基于您的代码的可运行版本:

CREATE FUNCTION [GtinCheckDigit] (@Input VARCHAR(17))
RETURNS VARCHAR(18)
BEGIN
DECLARE @CD VARCHAR(18);
WITH ReverseInput(S) AS (
    SELECT REVERSE(@Input)
), CharCount(N) AS (
    SELECT n from (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16),(17)) a(n)
), CharPos(N, S) AS (
    SELECT TOP (LEN(@Input)) CharCount.N, SUBSTRING(ReverseInput.S, CharCount.N, 1)
    FROM CharCount CROSS JOIN ReverseInput
), Multiplier(N) AS (
    SELECT S * CASE WHEN N % 2 = 0 THEN 1 ELSE 3 END
    FROM CharPos
), Checksum(N) AS (
    SELECT CASE WHEN SUM(N) % 10 > 0 THEN 10 - SUM(N) % 10 ELSE 0 END
    FROM Multiplier
)
SELECT @CD = @Input + CAST(N AS CHAR(1)) from Checksum;
RETURN @CD;
END
GO

【讨论】:

不应该返回VARCHAR(18)吗? @Emilio 我想知道同样的事情。但如果输入实际上只有 13-14 个字符,那么我不知道为什么它一开始那么长。

以上是关于在 SQL Server 中计算 GS1 校验位的标量值函数的主要内容,如果未能解决你的问题,请参考以下文章

M1卡校验位如何计算

计算机组成原理校验码

SQL Server 和带有哈希字节的持久计算字段

用户定义函数内的 Sql Server 表结构

关于SQL SERVER数据页checksum校验算法整理

SQL SERVER数据页checksum校验算法