sql >> Databasteknik >  >> RDS >> PostgreSQL

Postgres-funktionen skapar men körs inte

Jag hade en liknande situation - funktion med bred parameterlista. Med så kallade namngivna parametrar , du behöver inte respektera en ordning av parametrar. Koden är längre, men (hoppas jag) mer läsbar och robustare.

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$

Denna funktion kan anropas med namngivna parametrar notation:

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

Observera:När jag använder fel typ - Postgres rapporterar meddelande:

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.

Meddelandet är giltigt, men det är inte rent. Det är en kostnad för funktionsöverbelastningsstöd. Det finns andra knep, hur man delar upp lång parameterlista och hur man hittar dessa problem mer bekvämt.

Postgres stöder anpassade typer. Du kan använda det:

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

du kan skriva en konstruktorfunktioner:

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$

Att skapa detta system kräver en del arbete och det är praktiskt endast för system med lång livslängd. Å andra sidan minskar det en kostnad för framtida underhållsarbete.

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$

Nu är fler notationer (kombinationer av notationer) möjliga:

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

(1 row)

Konstruktörer hjälper till med fellokalisering:

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. Hur man frågar med en where-klausul i mysql json-tabellen

  2. Spåra den senaste ändringens tidsstämpel för en rad i Postgres

  3. SQLite INTERSECT Operator

  4. Fyll i datamängd med tabellnamn från lagrad procedur