检查MySQL中的无效UPC

时间:2015-02-08 17:39:40

标签: mysql

我有一个带有UPC代码列的mysql表。

我如何检查无效的?

这里有一个网站http://www.ehow.com/how_6810204_verify-upc-number.html,它显示了验证UPC的过程,但是如何将其转换为mysql查询或函数。

1 个答案:

答案 0 :(得分:1)

这是一个MySQL函数,用于计算UPC aka GTIN代码的校验位:

DELIMITER $$
CREATE DEFINER=`databasename`@`%` FUNCTION `gs1_checkdigit`(base VARCHAR(17)) RETURNS char(1) CHARSET utf8
    DETERMINISTIC
BEGIN
    ##
    ##  NAME
    ##      gs1_checkdigit -- calculate checkdigit for barcode numbers
    ##
    ##  SYNOPSIS
    ##      check_digit = gs1_checkdigit("NUMBER_WITHOUT_CHECKDIGIT")
    ##
    ##  DESCRIPTION
    ##      Given a GS1 input identifier (company_prefix + product_id)
    ##      without a check digit, returns the check digit that should
    ##      be appended to the input to be a valid identifier.
    ##
    ##      Can be used for inputs of any length. This is to accommodate
    ##      various GS1 standards ranging from GTIN-8 (7 input digits) to
    ##      SSCC (17 input digits). This function does NOT validate the
    ##      input length -- i.e. there is no valid 15-digit input length
    ##      in the GS1 standard, but this function will accept 15 digits.
    ##
    ##  OPTIONS
    ##      base        Input digits as a VARCHAR
    ##
    ##  RETURNS
    ##      Check digit as a CHAR(1)
    ##
    ##  EXAMPLES
    ##      SELECT gs1_checkdigit("05042829526")
    ##      --> 7
    ##
    ##  NOTES
    ##      Formula: http://www.gs1.org/how-calculate-check-digit-manually
    ##
    ##      Test cases: https://www.gs1us.org/tools/build-a-sample-upc-barcode
    ##
    ##------------------------------------------------------------------------
    ##
    ##  Local variables
    DECLARE odds INTEGER DEFAULT 0;     ## sum of odd positions
    DECLARE evens INTEGER DEFAULT 0;    ## sum of even positions
    DECLARE total INTEGER DEFAULT 0;    ## position-weighted sum
    DECLARE len INTEGER;                ## input string length
    DECLARE pos INTEGER DEFAULT 0;      ## current digit position
    DECLARE digit INTEGER;              ## current digit as INT
    DECLARE cd INTEGER;                 ## check digit for output
    ##
    ##  Main calculation
    SET len = LENGTH(base);
    mainloop: LOOP
        ##
        ##  Get digits, from the right
        SET digit = CAST(SUBSTRING(base, len-pos, 1) AS SIGNED INTEGER);
        ##
        ##  Example:
        ##
        ##     Input "12345678901" -- "X" is check digit placeholder
        ##     +-+-+-+-+-+-+-+-+-+-+-+-+
        ##     |1|2|3|4|5|6|7|8|9|0|1|X|
        ##     +-+-+-+-+-+-+-+-+-+-+-+-+
        ##      |                   |
        ##      "pos" 10 position   "pos" 0 position
        ##
        ##     Weighting factor by position
        ##     +-+-+-+-+-+-+-+-+-+-+-+-+
        ##     |3|1|3|1|3|1|3|1|3|1|3|0| 
        ##     +-+-+-+-+-+-+-+-+-+-+-+-+
        ##
        ##
        ##  Test cases:
        ##
        ##      SELECT gs1_checkdigit('04210000526');  ## 4
        ##      SELECT gs1_checkdigit('03600029145');  ## 2
        ##      SELECT gs1_checkdigit('05042829526');  ## 7
        ##      SELECT gs1_checkdigit('19147000000');  ## 0
        ##      SELECT gs1_checkdigit('19147056187');  ## 7
        ##      SELECT gs1_checkdigit('19147099999');  ## 1
        ##      SELECT gs1_checkdigit('62910415002');  ## 4
        ##
        IF (pos % 2 = 0)
        THEN
            SET evens = evens + digit;
        ELSE
            SET odds = odds + digit;
        END IF;
        ##
        ##  Bump the loop
        SET pos = pos + 1;
        IF (pos < LEN)
        THEN
            ITERATE mainloop;
        END IF;
        LEAVE mainloop;
    END LOOP mainloop;
    ##
    ##  GTIN formula
    SET total = odds + (3 * evens);
    SET cd = total % 10;
    IF (cd <> 0)
    THEN
        SET cd = 10 - cd;
    END IF;
    ##
    RETURN (CAST(cd AS CHAR));
END$$
DELIMITER ;

您可以使用以下查询找到无效的UPC(即GTIN):

SELECT
    upcfield as bad_upc
FROM
    upctable
WHERE
    RIGHT(upcfield, 1) <> gs1_checksum(LEFT(upcfield, LENGTH(upcfield)-1);