PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Funkcja Postgres tworzy, ale nie wykonuje

Miałem podobną sytuację - funkcja z szeroką listą parametrów. Z tak zwanymi nazwanymi parametrami , nie musisz przestrzegać kolejności parametrów. Kod jest dłuższy, ale (mam nadzieję) bardziej czytelny i solidniejszy.

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$

Tę funkcję można wywołać z nazwanymi parametrami notacja:

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

Uwaga:Kiedy używam niewłaściwego typu - Postgres zgłasza wiadomość:

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.

Wiadomość jest poprawna, ale nie jest czysta. Jest to koszt obsługi przeciążania funkcji. Jest jeszcze inna sztuczka, jak podzielić długą listę parametrów i jak wygodniej znaleźć te problemy.

Postgres obsługuje typy niestandardowe. Możesz go użyć:

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

możesz napisać funkcje konstruktora:

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$

Stworzenie tego systemu wymaga trochę pracy i jest praktyczne tylko w przypadku systemów o długiej żywotności. Z drugiej strony zmniejsza to koszty przyszłych prac konserwacyjnych.

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$

Teraz możliwych jest więcej notacji (kombinacji notacji):

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

(1 row)

Konstruktorzy pomagają w lokalizacji błędów:

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. Jak znaleźć odstęp między dwiema datami w PostgreSQL

  2. Eksportuj wyniki zapytań z BigQuery do Postgres

  3. Zapytanie zagnieżdżone w squeel

  4. Co to jest bajt typu danych i kiedy powinienem go użyć?

  5. Nowe funkcje zgodności z Oracle w PostgresPlus Advanced Server 9.3Beta