2

我有一个 15 位数的客户编号,我需要计算该值的校验位。为了得出校验位,我使用 Excel(公式如下)。

这个公式基于一种叫做 Luhn 算法的东西(我认为这是正确的拼写)。15 位客户编号存储在 SQL Server 2000 数据库中。

我希望能够使用 T-SQL 函数而不是 Excel 来进行此计算。有谁知道如何在 SQL Server 2000 数据库上使用 T-SQL 来做到这一点?

Excel 公式将给我一个 15 位数字的校验位:

=MOD(SUMPRODUCT(-MID(TEXT(MID(A2,ROW(INDIRECT("1:"&LEN(A2))),1)*(MOD(ROW(INDIRECT("1:"&LEN(A2)))+LEN(A2)+1,2)+1),"00"),{1,2},1)),10)
4

4 回答 4

5
CREATE FUNCTION dbo.fnGetLuhn
(
    @Luhn VARCHAR(7999)
)
RETURNS VARCHAR(8000)
AS
BEGIN
    IF @Luhn LIKE '%[^0-9]%'
        RETURN @Luhn

    DECLARE @Index SMALLINT,
        @Multiplier TINYINT,
        @Sum INT,
        @Plus TINYINT

    SELECT  @Index = LEN(@Luhn),
        @Multiplier = 2,
        @Sum = 0

    WHILE @Index >= 1
        SELECT  @Plus = @Multiplier * CAST(SUBSTRING(@Luhn, @Index, 1) AS TINYINT),
            @Multiplier = 3 - @Multiplier,
            @Sum = @Sum + @Plus / 10 + @Plus % 10,
            @Index = @Index - 1

    RETURN  @Luhn + CASE WHEN @Sum % 10 = 0 THEN '0' ELSE CAST(10 - @Sum % 10 AS CHAR) END
END
于 2012-08-29T17:17:12.910 回答
0
declare @strCode varchar(15)
select @strCode = '123456789012345'

select
sum 
(
    (convert(int,substring(@strCode,number,1))* ((number+1) % 2 + 1) ) % 10 + 
    (convert(int,substring(@strCode,number,1))* ((number+1) % 2 + 1) ) / 10
) * 9 % 10 as checkdigit
from master.dbo.spt_values 
where type='p' and number between 1 and len (@strCode)
于 2012-08-24T21:29:27.160 回答
0

这是我用于 Luhn 数字计算的内容:

create FUNCTION dbo.[LuhnDigit]
(
    @input nvarchar(255)
)
RETURNS char
AS
begin

    declare @sum int = (
        select sum(comp/10+comp % 10) from (
            SELECT 
                (2-(n%2))*((ascii(substring(@input,@len-n,1))-48)  % 10) as comp 
            from  (SELECT row_number() over (order by (select 1))-1 as n  FROM sys.objects) as a
            where n<=@len
        ) as a
    )

    return cast((10 - (@sum % 10)) % 10 as char);
END

即使对于非数字输入,此函数也会计算 Luhn 数字。

于 2015-02-03T16:34:43.830 回答
0

我对 Luhn 算法的方法:

CREATE FUNCTION [dbo].[F_CHECK_LUHN] (@DATA VARCHAR(32)) 
RETURNS BIT AS 

BEGIN 
-- valeurs limites 
IF @DATA IS NULL OR @DATA = '' RETURN NULL; 

DECLARE @Cpt INT = 0;
declare @C CHAR(1);
declare @Chiffre integer=0;  
declare @Somme integer=0;
declare @parity integer;
set  @parity=LEN(@DATA) % 2;

WHILE @Cpt < LEN(@DATA)
BEGIN

   SET @C = SUBSTRING(@DATA, @Cpt+1, 1);

    IF @C NOT BETWEEN '0' AND '9' RETURN NULL;

    set @Chiffre=CAST(@C AS SMALLINT);

    if ((@Cpt % 2) =@parity)
    begin
    set @Chiffre=@Chiffre*2;

        if (@Chiffre>9)
        begin
        set @Chiffre=@Chiffre-9;
        end;

    end;

    set @Somme=@Somme+@Chiffre;

    SET @Cpt = @Cpt + 1;
END;

RETURN CASE WHEN @Somme % 10 = 0 THEN 1 ELSE 0 end ;

END;
于 2017-12-31T11:41:12.663 回答