Функция контрольной суммы Verhoeff для PostgresSQL - PullRequest
0 голосов
/ 20 февраля 2020

Я нашел функцию контрольной суммы Verhoeff для PostgresSQL в: https://github.com/HIISORG/SNOMED-CT-PostgreSQL/blob/master/Verhoeff.sql

CREATE OR REPLACE FUNCTION verhoeff_generate (
  input numeric = NULL::numeric
)
RETURNS smallint AS $$
DECLARE
  _c SMALLINT := 0;
  _m SMALLINT;
  _i SMALLINT := 0;
  _n VARCHAR(255);
  -- Delcare array
  _d CHAR(100) := '0123456789123406789523401789563401289567401239567859876043216598710432765982104387659321049876543210';
  _p CHAR(80) := '01234567891576283094580379614289160435279453126870428657390127938064157046913258';
  _v CHAR(10) := '0432156789';
BEGIN
  _n := REVERSE(input::TEXT);
  WHILE _i<length(_n) LOOP
    _m := CAST(SUBSTRING(_p,(((_i + 1)%8)*10) + CAST(SUBSTRING(_n, _i+1, 1) AS SMALLINT) + 1, 1) AS SMALLINT);

    _c := CAST (substring(_d, (_c *10 + _m + 1), 1) AS SMALLINT);
    _i := _i + 1;
  END LOOP;

  RETURN CONCAT(input, CAST(substring(_v,_c+1,1) as SMALLINT));
END; $$
LANGUAGE 'plpgsql'
IMMUTABLE
RETURNS NULL ON NULL INPUT;

Я изменил RETURN, чтобы она объединялась ВХОД с контрольной суммой di git:

RETURN CONCAT(input, CAST(substring(_v,_c+1,1) as SMALLINT));

И я получаю ошибку:

[2020-02-20 11:53:19] [22003] ERROR: value "331010000014" is out of range for type smallint
[2020-02-20 11:53:19] Where: PL/pgSQL function verhoeff_generate(numeric) while casting return value to function's return type

Я пробовал:

 RETURN CONCAT(input, CAST(substring(_v,_c+1,1) as BIGINT));

По-прежнему получаю ту же ошибку.

1 Ответ

1 голос
/ 20 февраля 2020

Вы изменили код, который возвращает возвращаемое значение, в отличие от исходного smallint, который он возвращал, чтобы теперь быть строкой. (CONCAT функция выводит строку - вы можете приводить числа столько раз, сколько хотите, прежде чем передать их в concat, но они будут преобразованы в строки и затем объединены, а concat выведет строку, нет независимо от того, что вы в нее кормите)

CONCAT теперь возвращает вам строку, содержащую слишком много цифр (она слишком велика), чтобы поместиться в smallint - преобразование, которое PG пытается выполнить для вас неявно. Это основная проблема:

CREATE OR REPLACE FUNCTION return_big_number ()
RETURNS smallint AS $$
  RETURN '32769'; --string of a number that is too big for a smallint
END; $$

'32769' - это строка, которую нельзя преобразовать в smallint, потому что она просто слишком велика с точки зрения чисел - smallint ограничивается 32767. Аналогично, используя concat, вы генерирование строки, содержащей цифры, представляющие число, слишком большое для мелкого шрифта


Либо измените объявление функции вверху так, чтобы оно возвращало подходящую строку:

RETURNS smallint AS $$
        ^^^^^^^^
       change this to perhaps "RETURNS text AS $$"

Или если вывод в виде цифр c вам больше подходит, измените функцию, чтобы она объявляла возвращаемый тип данных цифр c, который может представлять больше цифр, чем строчные буквы, и изменяйте вычисление возвращаемого значения, чтобы сохранить его цифрами c (умножьте входное значение на некоторую степень 10 и добавьте контрольную сумму вместо того, чтобы изменять входные данные в строку и объединять контрольную сумму)

...