sql >> Database teknologi >  >> RDS >> PostgreSQL

PL/pgSQL kolonnenavn er det samme som variabel

Forudsat id_pracownika er den PRIMARY KEY af bordet. Eller i det mindste defineret UNIQUE . (Hvis det ikke er NOT NULL , NULL er en hjørnekasse.)

SELECT eller INSERT

Din funktion er en anden implementering af "SELECT or INSERT" - en variant af UPSERT problem, som er mere komplekst i lyset af samtidig skrivebelastning, end det ser ud til. Se:

  • Er SELECT eller INSERT i en funktion, der er tilbøjelig til løbsforhold?

Med UPSERT i Postgres 9.5 eller nyere

I Postgres 9.5 eller nyere brug UPSERT (INSERT ... ON CONFLICT ... ) Detaljer i Postgres Wiki. Denne nye syntaks gør et rent stykke arbejde :

CREATE OR REPLACE FUNCTION hire(
        _id_pracownika integer
      , _imie varchar
      , _nazwisko varchar
      , _miasto varchar
      , _pensja real)
  RETURNS text
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO pracownicy
          ( id_pracownika, imie, nazwisko, miasto, pensja)
   VALUES (_id_pracownika,_imie,_nazwisko,_miasto,_pensja);
   ON     CONFLICT DO NOTHING
   RETURNING 'OK';

   IF NOT FOUND THEN
      RETURN 'JUZ ISTNIEJE';
   END IF;
END
$func$;

Tabelkvalificerer kolonnenavne for at tvetydige, hvor det er nødvendigt. (Du kan også præfikse funktionsparametre med funktionsnavnet, men det bliver nemt akavet.)
Men kolonnenavne i mållisten for en INSERT er muligvis ikke bordkvalificeret. (Aldrig tvetydig alligevel.)

Det er bedst at undgå sådanne uklarheder på forhånd, det er mindre udsat for fejl. Nogle (inklusive mig) kan lide at gøre det ved at sætte en understregning foran alle funktionsparametre og variable.

Hvis du positivt bruger et kolonnenavn som funktionsparameternavn også, en måde at undgå navngivningskollisioner på er at bruge et ALIAS inde i funktionen. Et af de sjældne tilfælde, hvor ALIAS er faktisk nyttigt.

Eller reference funktionsparametre efter ordensposition:$1 for id_pracownika i dette tilfælde.

Hvis alt andet fejler, kan du bestemme, hvad der skal have forrang ved at indstille #variable_conflict . Se:

  • Navngivningskonflikt mellem funktionsparameter og resultat af JOIN med USING-sætning

Der er mere:

  • Der er forviklinger ved RETURNING klausul i en UPSERT. Se:

    • Hvordan bruger man RETURNING med ON CONFLICT i PostgreSQL?
  • Strengliteraler (tekstkonstanter) skal være omgivet af enkelte anførselstegn:'OK', ikke "OK" . Se:

    • Indsæt tekst med enkelte anførselstegn i PostgreSQL
  • At tildele variabler er forholdsvis dyrere end i andre programmeringssprog. Hold opgaver på et minimum for den bedste ydeevne i plpgsql. Gør så meget som muligt i SQL-sætninger direkte.

  • VOLATILE COST 100 er standard dekoratører til funktioner. Det er ikke nødvendigt at stave dem ud.

Uden UPSERT i Postgres 9.4 eller ældre

...
   IF EXISTS (SELECT FROM pracownicy p
             WHERE  p.id_pracownika = hire.id_pracownika) THEN
      RETURN 'JUZ ISTNIEJE';
   ELSE
      INSERT INTO pracownicy(id_pracownika,imie,nazwisko,miasto,pensja)
      VALUES (hire.id_pracownika,hire.imie,hire.nazwisko,hire.miasto,hire.pensja);
    
      RETURN 'OK';
   END IF;
...

I en EXISTS udtryk, SELECT listen er ligegyldig. SELECT id_pracownika , SELECT 1 , eller endda SELECT 1/0 - alt det samme. Bare brug en tom SELECT liste. Kun eksistensen af ​​en kvalificerende række har betydning. Se:

  • Hvad er nemmere at læse i EXISTS underforespørgsler?


  1. opbygge dynamisk SQL-forespørgsel med psycopg2 python-bibliotek og ved hjælp af gode konverteringsværktøjer

  2. Sådan konverteres en postgres-database til sqlite

  3. Online skemaopgradering i MySQL Galera Cluster ved hjælp af RSU-metoden

  4. PostgreSQL - Erstat HTML-enheder