سؤال

لقد قمت بتنفيذ خوارزمية فحص "MOD 10" باستخدام SQL، لأن عنوان خدمة الخدمة البريدية الأمريكية تغيير خدمة Keyline وفقا للطريقة الموجودة في مستندها، ولكن يبدو أنني أحصل على أرقام خاطئة! لدينا سلاسل المدخلات لدينا فقط أرقام فيها، مما يجعل الحساب أسهل قليلا. عندما أقارن نتائجي مع النتائج من تطبيق الاختبار، أحصل على أرقام مختلفة. أنا لا أفهم ما يجري؟ هل يرى أي شخص أي شيء خاطئ في خوارزمي؟ يجب أن تكون شيئا واضحا ...

يمكن العثور على وثائق الطريقة في الصفحة 12-13 من هذه الوثيقة:http://www.usps.com/cpim/ftp/pubs/pub8a.pdf.

يمكن العثور على تطبيق العينة في:http://ribbs.usps.gov/acs/documents/tech_guides/keyline.exe.

يرجى ملاحظة: قمت بإصلاح التعليمات البرمجية أدناه، بناء على المساعدة من مستخدمي المنتدى. هذا هو بحيث يتمكن القراء في المستقبل من استخدام التعليمات البرمجية بالكامل.

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
هل كانت مفيدة؟

المحلول

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

نصائح أخرى

لست متأكدا من السبب في أن تعبث بتمثيلات السلسلة بأكملها عند العمل في لغة مجموعة.

ربما كنت أفعل ذلك مثل أدناه. ركضت أربعة اختبارات من خلال وكلها ناجحة. يمكنك توسيع هذا بسهولة لمعالجة الشخصيات أيضا ويمكنك حتى جعل الجدول دائم إذا كنت ترغب حقا في القيام بذلك.

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

لماذا لدينا وزارة الدفاع الإضافية:

تحويل (varchar، 10 % <<-- ?

وتقول الوثيقة أن الرقم الأخير فقط يجب طرحه من 10. هل فاتني أي شيء؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top