sql >> Databáze >  >> RDS >> PostgreSQL

Název sloupce PL/pgSQL je stejný jako název proměnné

Za předpokladu id_pracownika je PRIMARY KEY tabulky. Nebo alespoň definované UNIQUE . (Pokud to není NOT NULL , NULL je rohový případ.)

SELECT nebo INSERT

Vaše funkce je další implementací "SELECT or INSERT" - varianta UPSERT problém, který je při současném zatížení zápisu složitější, než by se mohlo zdát. Viz:

  • Je SELECT nebo INSERT ve funkci náchylný k závodům?

S UPSERT v Postgres 9.5 nebo novější

V Postgres 9.5 nebo novějším použijte UPSERT (INSERT ... ON CONFLICT ... ) Podrobnosti na Postgres Wiki. Tato nová syntaxe dělá čistou práci :

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$;

Názvy sloupců kvalifikujte podle tabulky tak, aby byly v případě potřeby jednoznačné. (Parametry funkce můžete také předřadit názvem funkce, ale to se snadno stane nešikovným.)
Ale názvy sloupců v cílovém seznamu INSERT nemusí být kvalifikované pro stůl. (Stejně nikdy ne dvojznačné.)

Takovým nejednoznačnostem se nejlépe vyhněte a priori, je to méně náchylné k chybám. Někteří (včetně mě) to rádi dělají tak, že všechny parametry funkcí a proměnnou označují podtržítkem.

Pokud nutně potřebujete název sloupce také jako název parametru funkce, jeden způsob, jak se vyhnout kolizím pojmenování, je použít ALIAS uvnitř funkce. Jeden ze vzácných případů, kdy ALIAS je skutečně užitečné.

Nebo odkazujte na parametry funkce podle pořadové pozice:$1 pro id_pracownika v tomto případě.

Pokud vše ostatní selže, můžete se rozhodnout, co má přednost, nastavením #variable_conflict . Viz:

  • Konflikt pojmenování mezi parametrem funkce a výsledkem JOIN s klauzulí USING

Je toho víc:

  • RETURNING má složitost doložka v UPSERT. Viz:

    • Jak používat RETURNING s ON CONFLICT v PostgreSQL?
  • Řetězcové literály (textové konstanty) musí být uzavřeny v jednoduchých uvozovkách:'OK', nikoli "OK" . Viz:

    • Vložit text s jednoduchými uvozovkami v PostgreSQL
  • Přiřazení proměnných je poměrně dražší než v jiných programovacích jazycích. Pro dosažení nejlepšího výkonu v plpgsql udržujte úkoly na minimu. Udělejte co nejvíce přímo v příkazech SQL.

  • VOLATILE COST 100 jsou výchozí dekorátory funkcí. Není třeba je hláskovat.

Bez UPSERT v Postgres 9.4 nebo starší

...
   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;
...

V EXISTS výraz, SELECT na seznamu nezáleží. SELECT id_pracownika , SELECT 1 , nebo dokonce SELECT 1/0 - pořád to samé. Stačí použít prázdný SELECT seznam. Důležitá je pouze existence jakékoli kvalifikační řady. Viz:

  • Co je snazší číst v EXISTS dílčích dotazech?


  1. SQL trasování, událost 10046 v Oracle:trcsess, nástroj tkprof

  2. Existuje způsob, jak získat číslo řádku v Mysql jako rownum v oracle

  3. Jak získat data za poslední měsíc v MySQL

  4. SQL Server - připojte se pomocí ověřování systému Windows