it-swarm-eu.dev

Jaké jsou rozdíly mezi „uloženými procedurami“ a „uloženými funkcemi“?

Takže komentář od tato otázka uvádí, že v PostgreSQL existuje nepatrný rozdíl v „Stored Procedrues“ a „Stored Funtions“.

Komentář odkazuje na článek wikipedie , ale zdá se, že některé z nich neplatí (např. Že je lze použít v příkazu SELECT).

Sama syntaxe se zdá být trochu matoucí:

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
    BEGIN
       [...]
    END;
$emp_stamp$ LANGUAGE plpgsql;

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp();

Vytvoříte FUNCTION, ale označíte to jako PROCEDURE.

Jaký je tedy rozdíl mezi těmito dvěma?

37
DrColossos

Oficiálně má PostgreSQL pouze „funkce“. Spouštěcí funkce jsou někdy označovány jako „spouštěcí procedury“, ale toto použití nemá žádný zřetelný význam. Interně jsou funkce někdy označovány jako procedury, například v systémovém katalogu pg_proc. To je pozdržení od PostQUEL. Všechny funkce, které mohou někteří lidé (pravděpodobně se zkušenostmi v různých databázových systémech) asociovat s procedurami, jako je jejich význam pro zabránění vstřikování SQL nebo použití výstupních parametrů, platí také pro funkce, které existují v PostgreSQL.

Když však lidé v komunitě PostgreSQL hovoří o „uložených procedurách“ nebo „skutečných uložených procedurách“, často znamenají hypotetickou vlastnost funkčního objektu, který může ve svém těle spouštět a zastavovat transakce, což současné funkce nemohou dělat. V této souvislosti se termín "uložená procedura" používá obdobně jako u jiných databázových produktů. Nejasný nápad viz tento seznam e-mailů .

V praxi však toto rozlišení funkce versus procedura, pokud jde o jejich funkce pro řízení transakcí, není všeobecně přijímáno a určitě mnoho programátorů bez předpojatosti databáze vezme Pascalovu interpretaci procedury jako funkci bez návratové hodnoty. (Zdá se, že standard SQL zaujímá střední půdu v ​​tom, že procedura ve výchozím nastavení má jiné transakční chování než funkce, ale to lze upravit podle objekt.) Takže v každém případě, a zejména při pohledu na otázky týkající se zásobníku Exchange s velmi smíšeným publikem, byste se měli vyvarovat přílišného převzetí a používat jasnější výrazy nebo definovat vlastnosti, které očekáváte.

44
Peter Eisentraut

Pokud jde o DDL, Postgres nemá objekty procedur, pouze funkce. Funkce Postgres mohou vracet hodnoty nebo neplatné, takže se ujímají jak funkcí, tak procedur v jiných RDBMS. Slovo 'procedura' v create trigger odkazuje na funkci.

Z hlediska dokumentace Postgres je 'procedura' také synonymum pro databázový objekt nazvaný funkce, např .: " Spouštěcí procedura je vytvořena pomocí příkazu CREATE FUNCTION ".

Spouštěcí „procedury“ mají určitá pravidla: musí být deklarována jako funkce bez argumentů a návratového typu spouště . Příklad zde .

Termíny „uložená procedura“ a „uložená funkce“ se v PostgreSQL používají zaměnitelně a obecně se považují za totéž. Jiné databáze mohou rozlišovat mezi procedurou a funkcí (podobně jako VB rozlišuje mezi podprogramy a funkcemi).

Pokud funkce v PostgreSQL vrací něco, co se podobá tabulce, můžete použít výstup této funkce, jako by to byla standardní tabulka. Syntaxe CREATE TRIGGER Je trochu matoucí, ale domnívám se, že mohla existovat před dokončením standardu ANSI. Mám pouze kopii SQL: 2003, takže nemohu udělat mnohem víc, než spekulovat, proč je nomenklatura podivná.

TL; DR verze: s PostgreSQL je „procedura“ ekvivalentní „funkci“.

8
Jeremiah Peschka

V MSSQL je uložená procedura předkompilovaná sada příkazů sql.
Uložená procedura:

 - může mít mnoho vstupních a výstupních parametrů 
 - lze použít k úpravě databázových tabulek/struktur/dat 
 - obvykle se nepoužívají uvnitř příkazů insert/update/delete/select 
 - může mít více vstupních parametrů, ale vrací pouze jednu hodnotu (tj. řetězové zřetězení) 
 - může přijmout sadu jako vstup, vrátit jedinou hodnotu (tj. dbo.FindLargestPig (ListOfPigs))) 
 - vraťte tabulku (tj. vyberte * z dbo.ExplodeString („toto je seznam slov“))) 
 - lze použít v příkazech select/insert/update/delete 
 - NELZE použít k úpravě databázových tabulek/struktur/dat 
6
datagod

Krátká odpověď je, že funkce vrací hodnotu, ale procedura ne.

Tento rozdíl byl přítomen v perzistentních uložených modulech (SQL/PSM), který byl navržen pro SQL 1992. Nevím, zda se SQL/PSM někdy dostal do standardů.

Při porovnání přijaté odpovědi z abstraktní koncepční úrovně chápu rozdíl z hlediska funkčnosti a perspektivy vstupu/výstupu. Níže jsem použil sp a f k reprezentaci uložené procedury a funkce.

  1. Použití ve výrazu: sp nelze použít ve výrazu, zatímco funkce může, což znamená, že můžete použít vrácenou hodnotu z f uvnitř jiných příkazů, jako je

    select * 
    from table 
    where col_a < (select col_A from f())
    
  2. return a value: sp automaticky nevrací hodnotu, pokud nezadáte refcursor návratový typ, otevřete a nevrátíte kurzor; f vrátí výsledek v posledním příkazu, kde je vložena klauzule 'return', jako například select klauzule.

  3. vracet jednoduché/více sad výsledků: zde sady výsledků odkazují na seznam výsledků, které se mohou lišit ve formátu, jako je sada jednoho celého čísla, textového pole a dvou tabulek. sp může vracet více sad, pokud zadáte typ návratu návratu, otevřete a vrátíte kurzor. F však může vrátit pouze jeden typ sady.

Uložené procedury se obvykle používají k úpravě databázových dat nebo struktury, kde není potřeba návratová hodnota, jako je mazání, aktualizace, přetažení atd .; nebo situace, kdy je vyžadováno více sad výsledků. Funkce, na druhé straně, je většinou vybrána pro prosté dotazy.

Další podrobnosti týkající se mého vysvětlení naleznete v tomto odkazu: ložené procedury a funkce v PostgreSQL

2
Frank

Všimněte si, že v PostgreSQL 11 byly uložené procedury přidány jako nový objekt schématu. Nový postup můžete vytvořit pomocí CREATE PROCEDURE prohlášení.

Uložené procedury se liší od funkcí následujícími způsoby:

  • Uložené procedury nemají návratovou hodnotu
  • Transakce můžete odevzdat a vrátit zpět uvnitř uložených procedur, ale nikoli ve funkcích
  • Uloženou proceduru provedete pomocí příkazu CALL, nikoli pomocí příkazu SELECT.
1
d4nyll