<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title><![CDATA[Forum PostgreSQL - [SQL] Funkcje]]></title>
		<link>https://forum.postgresql.org.pl/viewtopic.php?id=1230</link>
		<description><![CDATA[Najświeższe odpowiedzi w [SQL] Funkcje.]]></description>
		<lastBuildDate>Wed, 15 Feb 2012 15:25:02 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Odp: [SQL] Funkcje]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=3443#p3443</link>
			<description><![CDATA[Dziękuje Ci za rady, pobawię się w każde zaproponowane przez Ciebie rozwiązanie i zobaczę, co z tego wyniknie :-)]]></description>
			<author><![CDATA[dummy@example.com (Shavei)]]></author>
			<pubDate>Wed, 15 Feb 2012 15:25:02 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=3443#p3443</guid>
		</item>
		<item>
			<title><![CDATA[Odp: [SQL] Funkcje]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=3442#p3442</link>
			<description><![CDATA[Niestety w ten sposób działa setof record, że trzeba określić typy przy inwokacji funkcji:

[quote]Calling this function is a little more complicated than calling the SRFs above. We need to give the system an idea of what types we expect this function to return as part of the query. PostgreSQL treats these functions somewhat similarly to table subselects and uses a similar syntax for providing this information as one would use to give aliases to subselect columns. [/quote]

Ew. widziałbym takie zastępcze rozwiązanie, żeby samą tabelę (np. w dodatku tymczasową via TEMPORARY) utworzyć wewnątrz funkcji np. przez CREATE TABLE AS (patrz [url]http://www.postgresql.org/docs/current/static/sql-createtableas.html),[/url] a póżniej po prostu się do niej odwołać przez zwykły select. Druga ew. możliwość, to zwrócenie przez funkcję kursora (refcursor) na taką dynamiczną tabelę, a następnie zabawa w odczytywanie go przez FETCH'a ([url]http://www.postgresql.org/docs/current/static/sql-fetch.html[/url]). Więcej na temat zwracania kursora przez funkcję możesz znaleźć na [url]http://www.postgresql.org/docs/current/static/plpgsql-cursors.html#AEN54791[/url]]]></description>
			<author><![CDATA[dummy@example.com (gszpetkowski)]]></author>
			<pubDate>Wed, 15 Feb 2012 14:32:35 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=3442#p3442</guid>
		</item>
		<item>
			<title><![CDATA[Odp: [SQL] Funkcje]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=3441#p3441</link>
			<description><![CDATA[Tak, wiem, że tak można, niestety to mnie nie ratuje, gdyż ilość kolumn w tabeli może zmieniać się dynamicznie. Dlatego zastanawiam się, czy da się jakoś napisać funkcję, która po wywołaniu zwróci wszystkie rekordy tabeli (lub kilku tabel, jeżeli w SELECT funkcji, zastosuje JOIN). Nie chcę (nie mogę) zastosować TYPE, bo nie wiem, co będzie zwracane.

Kombinuję na wszelkie sposoby, ale kompletnie nic mi nie działa.

Skonstruowałem sobie coś takiego, ale cały czas woła o kolumny (a column definition list is required for functions returning "record"):
[code]CREATE OR REPLACE FUNCTION f_profile(profile_number integer) RETURNS SETOF RECORD AS $$ 
DECLARE 
    profile_number ALIAS FOR $1; 
    result RECORD;
BEGIN
    FOR result IN
    SELECT * FROM ho_profile AS p 
        LEFT JOIN ho_card AS c ON c.card_profile_id = p.profile_id 
    WHERE p.profile_id = profile_number LIMIT 1
    LOOP
        RETURN NEXT result;
    END LOOP;
RETURN;
END;
$$ LANGUAGE 'PLPgSQL';[/code]]]></description>
			<author><![CDATA[dummy@example.com (Shavei)]]></author>
			<pubDate>Wed, 15 Feb 2012 13:28:21 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=3441#p3441</guid>
		</item>
		<item>
			<title><![CDATA[Odp: [SQL] Funkcje]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=3438#p3438</link>
			<description><![CDATA[A patrzyłeś może do [url]http://wiki.postgresql.org/wiki/Return_more_than_one_row_of_data_from_PL/pgSQL_functions[/url] ? Można zrobić tak, że funkcja zwraca setof record, a same typy określa się przy jej wywołaniu, jest tam pokazany przykład takiej funkcji.

W dokumentacji record jest określany jako pseudo-typ:

[quote]Identifies a function returning an [b]unspecified[/b] row type.[/quote]]]></description>
			<author><![CDATA[dummy@example.com (gszpetkowski)]]></author>
			<pubDate>Wed, 15 Feb 2012 11:57:41 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=3438#p3438</guid>
		</item>
		<item>
			<title><![CDATA[[SQL] Funkcje]]></title>
			<link>https://forum.postgresql.org.pl/viewtopic.php?pid=3437#p3437</link>
			<description><![CDATA[Witam,

Szukam rozwiązania, szperam w Manualu Postgresa, ale jakoś mi nie wychodzi. Próbuję stworzyć funkcję, pobierającą rekordy z bazy danych - to nie jest problemem. Problemem jest stworzenie "type". Normalnie definiuje pola, które ma zwracać, czyli np.
[code]CREATE TYPE type_profile (profile_id integer, profile_name text) itd.[/code]
a później tworzę sobie do tego funkcję, np.
[code]CREATE OR REPLACE function f_profile(profile_number integer) RETURNS SETOF type_profile AS $$ 
DECLARE 
    profile_number alias FOR $1; 
    result type_profile;
BEGIN     
    FOR result IN 
    SELECT * FROM tabela WHERE id = profile_number itd.
    LOOP
        RETURN NEXT result;
    END LOOP;
    RETURN;
END; 
$$ LANGUAGE 'plpgsql';[/code]

Teraz jednak nie wiem, ile pól (i jakie ma zwracać "type"), próbowałem coś w stylu:
[code]CRETATE TYPE type_profile(*)[/code]
Ale to oczywiście nie działa. Nie bardzo wiem, jak się do tego zabrać. Chcę zrobić funkcję, zwracającą mi rekordy, na podstawie parametru, ale chyba poległem...

Any ideas? :-)

Pozdrawiam,
Rafał]]></description>
			<author><![CDATA[dummy@example.com (Shavei)]]></author>
			<pubDate>Wed, 15 Feb 2012 11:33:54 +0000</pubDate>
			<guid>https://forum.postgresql.org.pl/viewtopic.php?pid=3437#p3437</guid>
		</item>
	</channel>
</rss>
