Frage

Ich habe die „MOD 10“ Prüfziffernalgorithmus mit SQL, für den US Postal Service Adresse Änderungsdienst Keyline nach der Methode in ihrem Dokument umgesetzt, aber es scheint, dass ich die falschen Zahlen bin immer! Unsere Eingabezeichenfolgen haben nur Zahlen in ihnen, so dass die Berechnung ein wenig leichter. Wenn ich meine Ergebnisse mit den Ergebnissen aus ihrer Testanwendung zu vergleichen, erhalte ich unterschiedliche Nummern. Ich verstehe nicht, was los ist? Hat jemand etwas falsch mit meinem Algorithmus sehen? Es hat etwas offensichtlich zu sein ...

Die Dokumentation für die Methode finden Sie auf Seite 12 bis 13 dieses Dokuments zu finden: http://www.usps.com/cpim/ftp/pubs/pub8a. pdf

Die Beispielanwendung finden Sie unter: http://ribbs.usps.gov/acs/documents/tech_guides/KEYLINE. EXE

ACHTUNG: Ich habe den Code unten festgelegt, basierend auf die Hilfe von Forum-Nutzer. Dies ist, so dass zukünftige Leser in der Lage sein werden, den Code in seiner Gesamtheit zu nutzen.

ALTER function [dbo].[udf_create_acs] (@MasterCustomerId varchar(26))
returns varchar(30)
as
begin
    --this implements the "mod 10" check digit calculation
    --for the US Postal Service ACS function, from "Publication 8A"
    --found at "http://www.usps.com/cpim/ftp/pubs/pub8a.pdf"
    declare @result varchar(30)
    declare @current_char int
    declare @char_positions_odd varchar(10)
    declare @char_positions_even varchar(10)
    declare @total_value int
    declare @check_digit varchar(1)

    --These strings represent the pre-calculated values of each character
    --Example: '7' in an odd position in the input becomes 14, which is 1+4=5
    -- so the '7' is in position 5 in the string - zero-indexed
    set @char_positions_odd = '0516273849'
    set @char_positions_even = '0123456789'
    set @total_value = 0
    set @current_char = 1

    --stepping through the string one character at a time
    while (@current_char <= len(@MasterCustomerId)) begin
        --this is the calculation for the character's weighted value
        if (@current_char % 2 = 0) begin
            --it is an even position, so just add the digit's value
            set @total_value = @total_value + convert(int, substring(@MasterCustomerId, @current_char, 1))
        end else begin
            --it is an odd position, so add the pre-calculated value for the digit
            set @total_value = @total_value + (charindex(substring(@MasterCustomerId, @current_char, 1), @char_positions_odd) - 1)
        end

        set @current_char = @current_char + 1
    end

    --find the check digit (character) using the formula in the USPS document
    set @check_digit = convert(varchar,(10 - (@total_value % 10)) % 10)

    set @result = '#' + @MasterCustomerId + '   ' + @check_digit + '#'

    return @result
end
War es hilfreich?

Lösung

set @check_digit = convert(varchar, (10 - (@total_value % 10)) % 10)

Andere Tipps

Ich bin mir nicht sicher, warum Sie mit den ganzen String-Darstellungen sind in Unordnung, wenn Sie in einer Set-basierten Sprache zu arbeiten.

Ich würde wahrscheinlich tun es wie unten. Ich lief vier Tests durch und sie waren alle erfolgreich. Sie können dies leicht erweitern Zeichen zu handhaben, wie gut und man konnte sogar die Tabelle permanent zu speichern, wenn Sie wirklich das tun wollten.

CREATE FUNCTION dbo.Get_Mod10
(
    @original_string    VARCHAR(26)
)
RETURNS VARCHAR(30)
AS
BEGIN
    DECLARE
        @value_mapping TABLE (original_char CHAR(1) NOT NULL, odd_value TINYINT NOT NULL, even_value TINYINT NOT NULL)

    INSERT INTO @value_mapping
    (
        original_char,
        odd_value,
        even_value
    )
    SELECT '0', 0, 0 UNION
    SELECT '1', 2, 1 UNION
    SELECT '2', 4, 2 UNION
    SELECT '3', 6, 3 UNION
    SELECT '4', 8, 4 UNION
    SELECT '5', 1, 5 UNION
    SELECT '6', 3, 6 UNION
    SELECT '7', 5, 7 UNION
    SELECT '8', 7, 8 UNION
    SELECT '9', 9, 9

    DECLARE
        @i              INT,
        @clean_string   VARCHAR(26),
        @len_string     TINYINT,
        @sum            SMALLINT

    SET @clean_string = REPLACE(@original_string, ' ', '')
    SET @len_string = LEN(@clean_string)
    SET @i = 1
    SET @sum = 0

    WHILE (@i <= @len_string)
    BEGIN
        SELECT
            @sum = @sum + CASE WHEN @i % 2 = 0 THEN even_value ELSE odd_value END
        FROM
            @value_mapping
        WHERE
            original_char = SUBSTRING(@clean_string, @i, 1)

        SET @i = @i + 1
    END

    RETURN (10 - (@sum % 10)) % 10
END
GO

Warum haben wir einen zusätzlichen mod:

konvertieren (varchar, 10% << -

Das Dokument besagt, dass nur die letzte Ziffer subtrahiert werden muss, von 10. Habe ich etwas verpasst?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top