<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Forum PostgreSQL - Jakie rozwiązanie byłoby najlepsze?]]></title>
	<link rel="self" href="http://forum.postgresql.org.pl/extern.php?action=feed&amp;tid=609&amp;type=atom"/>
	<updated>2011-07-08T15:27:44Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.postgresql.org.pl/viewtopic.php?id=609</id>
		<entry>
			<title type="html"><![CDATA[Odp: Jakie rozwiązanie byłoby najlepsze?]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=2597#p2597"/>
			<content type="html"><![CDATA[Wszystko już jasne. Dzieki.]]></content>
			<author>
				<name><![CDATA[janekw]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1248</uri>
			</author>
			<updated>2011-07-08T15:27:44Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=2597#p2597</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: Jakie rozwiązanie byłoby najlepsze?]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=2596#p2596"/>
			<content type="html"><![CDATA[[quote=gszpetkowski]Nie bardzo rozumiem co masz na myśli, wartości pnum są "na bieżąco" zachowywane w tabeli, dzięki czemu wiadomo, że nie należy ich ponownie wpisywać:

[/quote]


Miałem na myśli to, aby wszystkie odnalezione wartosci miały ten sam pnum - czyli aby mozna łatwo wybrac po pnum, ktore wartosci kID sa w jakis sposob ze soba polaczone.]]></content>
			<author>
				<name><![CDATA[janekw]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1248</uri>
			</author>
			<updated>2011-07-08T14:27:37Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=2596#p2596</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: Jakie rozwiązanie byłoby najlepsze?]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=2595#p2595"/>
			<content type="html"><![CDATA[Nie bardzo rozumiem co masz na myśli, wartości pnum są "na bieżąco" zachowywane w tabeli, dzięki czemu wiadomo, że nie należy ich ponownie wpisywać:

[code]IF isSet = false THEN[/code]]]></content>
			<author>
				<name><![CDATA[gszpetkowski]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1223</uri>
			</author>
			<updated>2011-07-08T14:23:10Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=2595#p2595</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: Jakie rozwiązanie byłoby najlepsze?]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=2594#p2594"/>
			<content type="html"><![CDATA[Serdeczne dziękuję za pomoc :) Czy dobrze myślę, że aby dla rozpatrywanego przypadku zachować wspólną wartość pnum, należałoby Twoją procedurę opakować zewnętrzną?]]></content>
			<author>
				<name><![CDATA[janekw]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1248</uri>
			</author>
			<updated>2011-07-08T14:12:49Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=2594#p2594</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Odp: Jakie rozwiązanie byłoby najlepsze?]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=2593#p2593"/>
			<content type="html"><![CDATA[Myślę, że najlepszym wyjściem jest napisanie procedury PL/pgSQL, która odpowiednio aktualizuje kolumnę pNUM. Przykładowo:

[code]DROP TABLE IF EXISTS tab;

CREATE TABLE tab (
    kID INT8,
    pID INT8,
    pNUM INT8,
    PRIMARY KEY(kID, pID)
);

DELETE FROM tab;
INSERT INTO tab (kID, pID) VALUES
    (1, 1), (2, 2), (3, 3), (1, 2), (4, 1),
    (5, 3), (6, 1), (7, 2), (8, 6), (9, 1),
    (1, 7), (10, 90),
    (6, 4);[/code]

Procedura:

[code]CREATE OR REPLACE FUNCTION updateTab(kStart INT8, deep INT8 DEFAULT 1)
RETURNS void AS $$
DECLARE
    p INT8;
    k INT8;
    isSet boolean;
BEGIN
    UPDATE tab SET pNUM = kStart WHERE kID = kStart;
    FOR p IN SELECT pID FROM tab WHERE kID = kStart
    LOOP
        FOR k IN SELECT kID FROM tab WHERE pID = p
        LOOP
            SELECT INTO isSet pNUM IS NOT NULL FROM tab WHERE kID = k LIMIT 1;
            RAISE NOTICE 'k=%, isSet=%', k, isSet;
            IF isSet = false THEN
                RAISE NOTICE 'updateTab(%, %)', k, deep + 1;
                PERFORM updateTab(k, deep + 1);
            END IF;
        END LOOP;
    END LOOP;
    RETURN;
END $$
LANGUAGE 'plpgsql';[/code]

Uruchomienie:

[code]SELECT updateTab(1);[/code]

Przebieg:

[code]NOTICE:  k=4, isSet=f
NOTICE:  updateTab(4, 2)
NOTICE:  k=6, isSet=f
NOTICE:  updateTab(6, 3)
NOTICE:  k=9, isSet=f
NOTICE:  updateTab(9, 4)
NOTICE:  k=1, isSet=t
NOTICE:  k=4, isSet=t
NOTICE:  k=6, isSet=t
NOTICE:  k=9, isSet=t
NOTICE:  k=1, isSet=t
NOTICE:  k=4, isSet=t
NOTICE:  k=6, isSet=t
NOTICE:  k=6, isSet=t
NOTICE:  k=9, isSet=t
NOTICE:  k=1, isSet=t
NOTICE:  k=4, isSet=t
NOTICE:  k=6, isSet=t
NOTICE:  k=9, isSet=t
NOTICE:  k=1, isSet=t
NOTICE:  k=2, isSet=f
NOTICE:  updateTab(2, 2)
NOTICE:  k=7, isSet=f
NOTICE:  updateTab(7, 3)
NOTICE:  k=1, isSet=t
NOTICE:  k=2, isSet=t
NOTICE:  k=7, isSet=t
NOTICE:  k=1, isSet=t
NOTICE:  k=2, isSet=t
NOTICE:  k=7, isSet=t
NOTICE:  k=1, isSet=t
NOTICE:  k=1, isSet=t[/code]

Wynik:

[code]TABLE tab ORDER BY kID;
 kid | pid | pnum 
-----+-----+------
   1 |   1 |    1
   1 |   7 |    1
   1 |   2 |    1
   2 |   2 |    2
   3 |   3 |     
   4 |   1 |    4
   5 |   3 |     
   6 |   4 |    6
   6 |   1 |    6
   7 |   2 |    7
   8 |   6 |     
   9 |   1 |    9
  10 |  90 |     
(13 rows)[/code]

Parametr deep pozwala określic głębokość/poziom, łatwo np. dodać warunek, który blokuje możliwość nieskończonej rekurencji.]]></content>
			<author>
				<name><![CDATA[gszpetkowski]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1223</uri>
			</author>
			<updated>2011-07-08T13:47:55Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=2593#p2593</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Jakie rozwiązanie byłoby najlepsze?]]></title>
			<link rel="alternate" href="https://forum.postgresql.org.pl/viewtopic.php?pid=2592#p2592"/>
			<content type="html"><![CDATA[Witam,

Nie bardzo potrafię sobie poradzić z następującym tematem: mam tabele tab(kID INT8, pID INT8, pNUM INT8). Kluczem głównym jest klucz złożony [kID,pID]. Mam np. takie krotki w tabeli:
[1, 1,null]
[2, 2,null]
[3, 3,null]
[1, 2,null]
[4, 1,null]
[5, 3,null]
[6, 1,null]
[7, 2,null]
[8, 6,null]
[9, 1,null]
[1, 7,null]
[10,90,null]

Dla wskazanego kID chcialbym znależć wszystkie inne kID ktore wiaza przez wspolne pole pID.
Przykladowo biore kID=1 i chce znalezc inne kID ktore wiaza sie przez wspolne pID, czyli: 
kID=1 => pID =1, ale dla pID=1 mam dodatkowo kID=4, kID=6, kID=9 => i tu znowu szukam dla uzsyskanych kID powiazan
kID=1 => pID =2, dla pID=2 mam dodatkowo kID=2, kID=7 => i tu znowu szukam dla uzsyskanych kID powiazan
kID=1 => pID =7, brak innych

Koniec bedzie wowczas gdy nie znajde juz zadnego nowego kID.
Wszystkie znalezione w ten sposob kID zostana oznaczone ta sama waroscia w polu pNUM.

Pasuje mi zastosowanie rekurencji w funkcji ale nie bardzo wiem jak jej uzyc.

Pozdrawiam]]></content>
			<author>
				<name><![CDATA[janekw]]></name>
				<uri>https://forum.postgresql.org.pl/profile.php?id=1248</uri>
			</author>
			<updated>2011-07-07T21:48:47Z</updated>
			<id>https://forum.postgresql.org.pl/viewtopic.php?pid=2592#p2592</id>
		</entry>
</feed>
