PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Функцията Postgres създава, но не изпълнява

Имах подобна ситуация - функция с широк списък с параметри. С така наречените наименувани параметри , не е необходимо да спазвате ред от параметри. Кодът е по-дълъг, но (надявам се) по-четлив и по-стабилен.

CREATE TABLE tab(name text, surname text, address text, city text, zip text);

CREATE OR REPLACE FUNCTION public.fx(name text, surname text,
                                     address text, city text, zip text)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
  INSERT INTO tab(name, surname, address, city, zip)
    VALUES(fx.name, fx.surname, fx.address, fx.city, fx.zip);
  -- ... some other logic
END;
$function$

Тази функция може да бъде извикана с наименувани параметри нотация:

SELECT fx(name := 'Pavel', surname := 'Stehule',
          address := 'Skalice 12', city := 'Benesov', zip := '12');

Внимание:Когато използвам грешен тип - Postgres докладва съобщение:

postgres=#   SELECT fx(name := 'Pavel', surname := 'Stehule',
              address := 'Skalice 12', city := 'Benesov', zip := 12);
ERROR:  function fx(name := unknown, surname := unknown, address := unknown, city := unknown, zip := integer) does not exist
LINE 1: SELECT fx(name := 'Pavel', surname := 'Stehule',
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.

Съобщението е валидно, но не е чисто. Това са разходи за поддръжка на претоварване на функциите. Има друг трик, как да разделите дълъг списък с параметри и как да намерите тези проблеми по-удобно.

Postgres поддържа потребителски типове. Можете да го използвате:

CREATE TYPE person_type AS (name text, surname text);
CREATE TYPE address_type AS (address text, city text, zip text);

можете да напишете конструктор функции:

CREATE OR REPLACE FUNCTION public._person_type(name text, surname text)
RETURNS person_type
LANGUAGE plpgsql
AS $function$
DECLARE r person_type;
BEGIN
  r.name = name;
  r.surname = surname;
  RETURN r;
END;
$function$

CREATE OR REPLACE FUNCTION public._address_type(address text, city text, zip text)
RETURNS address_type
LANGUAGE plpgsql
AS $function$ DECLARE r address_type;
BEGIN
  r.address = address;
  r.city = city;
  r.zip = zip;
  RETURN r;
END;
$function$

Създаването на тази система изисква малко работа и е практично само за дълготрайни системи. От друга страна, това намалява разходите за бъдеща поддръжка.

CREATE OR REPLACE FUNCTION public.fx(p person_type, a address_type)
RETURNS void
LANGUAGE plpgsql
AS $function$
BEGIN
  INSERT INTO tab(name, surname, address, city, zip)
    VALUES(p.name, p.surname, a.address, a.city, a.zip);
   -- ... some other logic
END;
$function$

Сега са възможни повече обозначения (комбинация от обозначения):

postgres=# SELECT fx(_person_type('Pavel','Stehule'),
postgres(#           _address_type('Skalice 12','Benesov', '25601'));
 fx 
----

(1 row)

Конструкторите помагат при локализиране на грешки:

postgres=# SELECT fx(_person_type('Pavel','Stehule'),
          _address_type('Skalice 12','Benesov', 25601));
ERROR:  function _address_type(unknown, unknown, integer) does not exist
LINE 2:           _address_type('Skalice 12','Benesov', 25601));
                  ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да направя процент/общо в SQL?

  2. Postgres, прости заявки, които не използват индекс

  3. използвайте \set променлива вътре в блока за деклариране на plpgsql

  4. Как да получите текущото време (без часова зона) в PostgreSQL

  5. Какво означава, когато процес на PostgreSQL е неактивен в транзакцията?