ОШИБКА PostgreSQL: нет встроенной функции с именем " (состояние SQL 42883)

Я пытаюсь добавить в свой 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, но не знаю, что происходит.

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


person Javier    schedule 27.09.2011    source источник


Ответы (2)


В дополнение к тому, что уже указал 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
person Erwin Brandstetter    schedule 08.10.2011

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

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

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

person a_horse_with_no_name    schedule 27.09.2011