<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>IT blog &#187; trigger</title>
	<atom:link href="http://szj.cz/tag/trigger/feed/" rel="self" type="application/rss+xml" />
	<link>http://szj.cz</link>
	<description>internet, linux, novinky, programování</description>
	<lastBuildDate>Sat, 12 Sep 2015 11:14:32 +0000</lastBuildDate>
	<language>cs-CZ</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.2.2</generator>
	<item>
		<title>Funkce a triggery v PostgreSQL</title>
		<link>http://szj.cz/funkce-a-triggery-v-postgresql/</link>
		<comments>http://szj.cz/funkce-a-triggery-v-postgresql/#comments</comments>
		<pubDate>Sun, 05 Apr 2015 12:40:25 +0000</pubDate>
		<dc:creator><![CDATA[fredomgc]]></dc:creator>
				<category><![CDATA[Programování]]></category>
		<category><![CDATA[funkce]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[trigger]]></category>

		<guid isPermaLink="false">http://szj.cz/?p=950</guid>
		<description><![CDATA[Následující článek se bude hodit každému, kdo již má určité zkušenosti s SQL a rád by si vyzkoušel napsat vlastní funkci nebo trigger. Začneme velmi zvolna, nejprve si představíme, jak napsat jednoduchou funkci a následně se vrhneme na triggery. Vlastní funkce v PostgreSQL Funkce dělá přesně to, co její matematický protějšek. Pro vstupní hodnotu vrátí určitý [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://szj.cz/wp-content/uploads/2015/03/postgresql-trigger.png"><img class="alignleft size-full wp-image-954" alt="postgresql-trigger" src="http://szj.cz/wp-content/uploads/2015/03/postgresql-trigger.png" width="128" height="128" /></a>Následující článek se bude hodit každému, kdo již má určité zkušenosti s SQL a rád by si vyzkoušel napsat <strong>vlastní funkci</strong> nebo <strong>trigger</strong>. Začneme velmi zvolna, nejprve si představíme, jak napsat jednoduchou funkci a následně se vrhneme na triggery.<strong><br />
</strong></p>
<h2>Vlastní funkce v PostgreSQL</h2>
<p>Funkce dělá přesně to, co její matematický protějšek. Pro vstupní hodnotu vrátí určitý údaj. My si nyní vytvoříme funkci, co nebude vyžadovat argument a vždy vrátí číslo jedna &#8212; to jen pro zahřátí, taková funkce samozřejmě není moc užitečná, ale alespoň se podíváme, jak vlastně vypadá její syntaxe.</p>
<pre class="brush: sql; title: ; notranslate">

CREATE FUNCTION test() RETURNS integer AS $$

SELECT 1 AS result;

$$ LANGUAGE SQL;

SELECT test(); --vypíše 1

</pre>
<p>Nejprve s pomocí <strong>CREATE FUNCTION</strong> vymezíme, že začínáme psát funkci. Poté uvedeme její název (zde <strong>test</strong>) a prázdnou závorku, protože nepřebíráme žádné argumenty. Databázový server zajímá, jaký datový typ bude naše funkce vracet, proto jej uvedeme (<strong>integer</strong>). Za klíčovým slovem <strong>AS</strong> začíná vymezení samotného těla funkce, které z obou strany obklopuje symbol dvou dolarů (<strong>$$</strong>). Závěrem uvedeme použitý jazyk (<strong>LANGUAGE SQL</strong>) a nezapomeneme na středník, podobně jako v těle funkce, ve kterém jednoduše s pomocí příkazu <strong>SELECT</strong> získáme číselnou hodnotu 1.</p>
<p>Pojďme zkusit něco užitečnějšího, naučíme se používat argumenty:</p>
<pre class="brush: sql; title: ; notranslate">

CREATE FUNCTION plus(integer, integer) RETURNS integer AS $$
 SELECT $1 + $2 AS result;
$$ LANGUAGE SQL;

SELECT plus(10, 5); --vypíše 15

SELECT plus(5, 'a'); --Error in query: ERROR: invalid input syntax for integer: &quot;a&quot;

</pre>
<p>Tato funkce umí sečíst dvě čísla. U argumentů uvádíme jen datový typ a na hodnotu se odkazujeme s pomocí dolaru a indexu (první argument je dostupný s pomocí <strong>$1</strong>).</p>
<p>Než se vhrneme na náš první trigger, smažeme z databáze vytvořené funkce. Udělá se to následovně:</p>
<pre class="brush: sql; title: ; notranslate">

DROP FUNCTION test();

DROP FUNCTION plus(integer, integer);

</pre>
<h2>Jednoduchý trigger v PostgreSQL</h2>
<p>Na úvod si představme, že máme tabulku <strong>human </strong> obsahující údaje o lidech. Uchováváme jedinečné ID, jméno, příjmení a oslovení. Napíšeme si trigger, který nám bude zmíněné oslovení generovat automaticky. Nejprve vytvoříme samotnou funkci, kterou server následně automaticky zavolá. Daná funkce nebude dělat nic jiného, než že vezme jméno i příjmení a spojí oba údaje mezerou.</p>
<p><a href="http://szj.cz/wp-content/uploads/2015/03/tabulka_human.png"><img class="aligncenter size-full wp-image-955" alt="tabulka_human" src="http://szj.cz/wp-content/uploads/2015/03/tabulka_human.png" width="547" height="242" /></a></p>
<pre class="brush: sql; title: ; notranslate">

CREATE FUNCTION concatenate() returns trigger AS $$
BEGIN
UPDATE human SET salutation = (NEW.name || ' ' || NEW.surname) WHERE id = NEW.id;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

</pre>
<p>Oproti zápisu funkce je zde několik rozdílů. Trigger <strong>nikdy nemá argumenty</strong> a jako návratový typ uvádíme slovo <strong>trigger</strong>. Do těla se nám dostala část <strong>BEGIN</strong> a <strong>END;</strong> (pozor na středník). Uvnitř těla smíme používat proměnnou <strong>NEW</strong>, která odkazuje na nově vytvořený/upravený řádek. Příkazem <strong>RETURN</strong> vracíme výsledek funkce (zde je <strong>NULL</strong>, protože nic vracet nechceme). Klauzule <strong>LANGUAGE</strong> obsahuje <strong>plpgsql</strong>, protože píšeme trigger pro PostgreSQL.</p>
<p>Pojďme nyní naší tabulku donutit, ať trigger volá automaticky při každém vložení hodnoty:</p>
<pre class="brush: sql; title: ; notranslate">

CREATE TRIGGER human_trigger AFTER INSERT ON human
FOR EACH ROW EXECUTE PROCEDURE concatenate();

</pre>
<p>Zápis je hodně upovídaný a osobně se mi špatně pamatuje. Zase se naopak dobře čte :-). Uvádíme pojmenování našeho triggeru (<strong>human_trigger</strong>), název tabulky (<strong>human</strong>) a samotnou funkci, co bude volána (<strong>concatenate()</strong>);</p>
<p>A nyní pozor, stačí nám spustit následující příkaz a v tabulce objevíme automaticky vygenerované oslovení:</p>
<pre class="brush: sql; title: ; notranslate">

INSERT INTO human(name, surname, salutation) VALUES ('Jan', 'Novák', '?');

</pre>
<p>Sloupec <strong>salutation</strong> nedovoluje hodnoty <strong>NULL</strong>, proto musíme nějakou uvést, i když bude následně přepsána triggerem. To je nepříjmené, pojďme si náš trigger vylepšit! Funkci nebudeme volat <strong>po</strong> zápisu řádku, ale <strong>před</strong> zápisem (a v tuto chvíli si vygenerujeme oslovení).</p>
<pre class="brush: sql; title: ; notranslate">

CREATE FUNCTION concatenate() returns trigger AS $$
BEGIN
NEW.salutation := NEW.name || ' ' || NEW.surname;
return new;
END;
$$ LANGUAGE plpgsql;

</pre>
<p>S pomocí proměnné <strong>NEW</strong> přiřadíme oslovení. Hotovu funkci poté budeme volat před provedením <strong>INSERT</strong> nebo v případě <strong>UPDATE</strong>:</p>
<pre class="brush: sql; title: ; notranslate">

CREATE TRIGGER human_trigger BEFORE INSERT OR UPDATE ON human
 FOR EACH ROW EXECUTE PROCEDURE concatenate();

</pre>
]]></content:encoded>
			<wfw:commentRss>http://szj.cz/funkce-a-triggery-v-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
