ОШИБКА PostgreSQL: нет встроенной функции с именем "(состояние SQL 42883) - PullRequest
0 голосов
/ 27 сентября 2011

Я пытаюсь добавить в свой PostgreSQL очень простую функцию для преобразования IP-адресов из целого числа в текстовый формат.

Это код функции:

CREATE FUNCTION  custom_int_to_ip(ip BIGINT)
RETURNS TEXT
AS
$$
DECLARE
octet1 BIGINT;
octet2 TINYINT;
octet3 TINYINT;
octet4 TINYINT;
restofip BIGINT;
BEGIN
octet1 = ip / 16777216;
restofip = ip - (octet1 * 16777216);
octet2 = restofip / 65536;
restofip  = restofip - (octet2 * 65536);
octet3 = restofip / 256;
octet4 = restofip - (octet3 * 256);
END; 
RETURN(CONVERT(TEXT, octet1) + '.' +
CONVERT(TEXT, octet2) + '.' +
CONVERT(TEXT, octet3) + '.' +
CONVERT(TEXT, octet4));
$$
LANGUAGE internal;

При воспроизведении я получаю следующую ошибку:

ERROR: there is no built-in function named "

И несколько строк ниже ...

SQL state: 42883

Пожалуйста, дайте мне знать, если кто-то может увидеть мою ошибку здесь, я пробовал разные синтаксисы и информацию поиска для определенного состояния SQL, но не имею понятия о том, что происходит.

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 27 сентября 2011

Здесь есть две ошибки:

  1. PostgreSQL использует стандартный оператор конкатенации строк ||, как почти все другие базы данных
  2. Нет convert функция в PostgreSQL, вы должны использовать to_char () для преобразования числа в строку

Кстати: знаете ли вы, что в PostgreSQL доступен собственный тип данных IP?

0 голосов
/ 08 октября 2011

В дополнение к тому, что a_horse_with_no_name уже указывало:

  • Используйте language plpgsql вместо language internal
  • MySQL и другиеиметь tinyint.В PostgreSQL вместо этого используйте smallint или int2 (синоним).См. Руководство о типах данных .А еще лучше, сделайте все переменные bigint в этом конкретном случае и сохраните дополнительное преобразование.
  • Используйте оператор присваивания := вместо =.= не имеет документов и может перестать работать без уведомления в будущей версии.Смотрите здесь: Забытый оператор присваивания "=" и обычное место ": ="
  • Перемещение END; в конец.
  • Вывод гарантированно будет таким жедля того же входа, поэтому сделайте функцию IMMUTABLE, чтобы ускорить его в определенных ситуациях.

Чтобы подвести итог всего этого:

CREATE OR REPLACE FUNCTION custom_int_to_ip(ip bigint)
RETURNS inet AS
$$
DECLARE
   octet1   bigint;
   octet2   bigint;
   octet3   bigint;
   octet4   bigint;
   restofip bigint;
BEGIN

octet1   := ip / 16777216;
restofip := ip - (octet1 * 16777216);
octet2   := restofip / 65536;
restofip := restofip - (octet2 * 65536);
octet3   := restofip / 256;
octet4   := restofip - (octet3 * 256);

RETURN (octet1::text || '.'
     || octet2::text || '.'
     || octet3::text || '.'
     || octet4::text);

END; 
$$
LANGUAGE plpgsql IMMUTABLE;

Вызов:

SELECT custom_int_to_ip(1231231231);

Выход:

73.99.24.255
...