tworzenie widoku/tabeli wewnatrz funkcji
Adam Przybyłek - 01-08-2006 01:49
tworzenie widoku/tabeli wewnatrz funkcji
Tabela node_AL ma zawierac krawedzie grafu acyklicznego, np relacje podwladny-przelozony. Tabela TC ma zawierac tranzytywne domkniecie tej relacji (jak zrobic tranzytywne domkniecie jest opisane na comp.databases.theory, watek Using Materialized Path to create a paths table). Tabela TC bedzie aktualizowana za kazdym razem kiedy wstawie rekord do node_AL. Na tabele node_AL nakladam wiec triggera. Wewnatrz triggera chcialem utworzyc na chwile pomocniczy widok (moze byc tabela lub tabela temporary), a przed zakonczeniem wykonywania triggera go usunac. Oracle w ogole nie chce pozwolic mi na utworzenie widoku/tabeli wewnatrz funkcji. W PostgreSQL wszystk dziala, ale tylko przy wstawianiu pierwszego rekordu. Przy wstawianiu kolejnego chwilowy widok w ogole nie chce sie utworzyc. Co robie zle? Ponizej pokazuje kod triggera, a wszystkie skrypty udostepniam na: http://snickers.ek.univ.gda.pl/~adam/tc.rar (nalezy odpalic all.sql).
CREATE OR REPLACE FUNCTION update_TC() RETURNS trigger AS ' DECLARE a INTEGER; b INTEGER; BEGIN a := NEW.id_entity; b := NEW.id_parent;
IF TG_OP = ''INSERT'' THEN --ponizszy widok tworzy sie tylko przy pierwszym wywolaniu triggera CREATE VIEW TC_NEW AS SELECT * FROM ( SELECT TC.id_entity As id_entity, b As id_ancestor FROM TC WHERE TC.id_ancestor = a UNION SELECT a As id_entity, TC.id_ancestor As id_ancestor FROM TC WHERE b = TC.id_entity UNION SELECT TC1.id_entity As id_entity, TC2.id_ancestor As id_ancestor FROM TC TC1, TC TC2 WHERE TC1.id_ancestor = a AND TC2.id_entity = b ) T;
CREATE VIEW TC_DELTA AS SELECT * FROM TC_NEW EXCEPT SELECT * FROM TC;
INSERT INTO TC SELECT * FROM TC_DELTA;
INSERT INTO TC Values (a,b);
DROP VIEW TC_DELTA; Drop VIEW TC_NEW; END IF;
RETURN NULL; END; ' LANGUAGE 'plpgsql';
Pozdrawiam, Adam
Paweł Matejski - 01-08-2006 01:51
Adam Przybyłek wrote: > Tabela node_AL ma zawierac krawedzie grafu acyklicznego, np relacje > podwladny-przelozony. Tabela TC ma zawierac tranzytywne domkniecie tej > relacji (jak zrobic tranzytywne domkniecie jest opisane na > comp.databases.theory, watek Using Materialized Path to create a paths > table).
Czuje się jak na wykładzie.
> Tabela TC bedzie aktualizowana za kazdym razem kiedy wstawie rekord > do node_AL. Na tabele node_AL nakladam wiec triggera. > Wewnatrz triggera chcialem utworzyc na chwile pomocniczy widok (moze byc > tabela lub tabela temporary), a przed zakonczeniem wykonywania triggera go > usunac. > Oracle w ogole nie chce pozwolic mi na utworzenie widoku/tabeli wewnatrz > funkcji. > W PostgreSQL wszystk dziala, ale tylko przy wstawianiu pierwszego rekordu.
A tak dać błąd jaki zwraca?
> Przy wstawianiu kolejnego chwilowy widok w ogole nie chce sie utworzyc. Co > robie zle?
Za bardzo kombinujesz.
> Ponizej pokazuje kod triggera, a wszystkie skrypty udostepniam na: > http://snickers.ek.univ.gda.pl/~adam/tc.rar (nalezy odpalic all.sql).
CREATE OR REPLACE FUNCTION update_TC() RETURNS trigger AS ' DECLARE a INTEGER; b INTEGER; BEGIN a := NEW.id_entity; b := NEW.id_parent;
IF TG_OP = ''INSERT'' THEN
INSERT INTO TC SELECT * FROM ( SELECT TC.id_entity As id_entity, b As id_ancestor FROM TC WHERE TC.id_ancestor = a UNION SELECT a As id_entity, TC.id_ancestor As id_ancestor FROM TC WHERE b = TC.id_entity UNION SELECT TC1.id_entity As id_entity, TC2.id_ancestor As id_ancestor FROM TC TC1, TC TC2 WHERE TC1.id_ancestor = a AND TC2.id_entity = b EXCEPT SELECT * FROM TC) s;
INSERT INTO TC Values (a,b); END IF;
RETURN NULL; END; ' LANGUAGE 'plpgsql';
Czy tak nie jest prościej?
-- P.M.
wk - 01-08-2006 01:51
Użytkownik "Adam Przybyłek" <adampap@panda.bg.univ.gda.pl> napisał w wiadomości news:eakevc$gic$1@news.task.gda.pl... > Wewnatrz triggera chcialem utworzyc na chwile pomocniczy widok (moze byc > tabela lub tabela temporary), a przed zakonczeniem wykonywania triggera go > usunac. > Oracle w ogole nie chce pozwolic mi na utworzenie widoku/tabeli wewnatrz > funkcji.
Bo w Oraclu jest trochę inaczej niz w PostgreSQLu.... W Oraclu masz stały obiekt "tablica tymczasowa", a jedynie dane wstawiane do niego są pamietane albo do czasu najbliższego commita w sesji, albo do czasu zakonczenia sesji, w ktorej zostały wstawione.
I nikt nie robi w Oraclu w tresci triggera zdania "create table" żeby na końcu zrobić "drop table". Uzywasz (jesli juz musisz) do tego celu własnie tablic tymczasowych (moga one miec swoje primary key itd, są wtedy "widoczne" takie ograniczenia tylko w stosunku do danych w danej sesji)
-- wk
Adam Przybyłek - 02-08-2006 00:06
Użytkownik "Paweł Matejski" <madej@spam.madej.pl.eu.org> napisał w wiadomości news:eakpel$i7d$1@inews.gazeta.pl... > > Tabela TC bedzie aktualizowana za kazdym razem kiedy wstawie rekord > > do node_AL. Na tabele node_AL nakladam wiec triggera. > > Wewnatrz triggera chcialem utworzyc na chwile pomocniczy widok (moze byc > > tabela lub tabela temporary), a przed zakonczeniem wykonywania triggera go > > usunac. > > Oracle w ogole nie chce pozwolic mi na utworzenie widoku/tabeli wewnatrz > > funkcji. > > W PostgreSQL wszystk dziala, ale tylko przy wstawianiu pierwszego rekordu. > > A tak dać błąd jaki zwraca? >
ERROR: relation with OID 22238 does not exist CONTEXT: SQL statement "INSERT INTO TC SELECT * FROM TC_DELTA" PL/pgSQL function "update_tc" line 34 at SQL statement
> > Przy wstawianiu kolejnego chwilowy widok w ogole nie chce sie utworzyc. Co > > robie zle? > > Za bardzo kombinujesz. > [...]
Tak. Twoja wersja dziala bez zarzutu, robi dokladnie to o co mi chodzilo i jest duzo ladniejsza od mojej. Dzieki. Chociaz nadal zastanawia mnie dlaczego przy wstawieniu pierwszego rekordu moj trigger dzialal, a przy drugim juz sie wywalal, bo nie chcial utworzyc widoku.
Pozdrawiam, Adam
Michał Kuratczyk - 02-08-2006 00:07
Adam Przybyłek wrote: > No wlasnie jak probowalem robic tymczasowa w Oracle wewnatrz triggera to > tez wywalal blad. Oto przyklad: > CREATE OR REPLACE TRIGGER updateTC > AFTER INSERT ON node_AL > FOR EACH ROW > BEGIN > Create global temporary table test ( > id integer > ); > END; > > Wywala taki blad: > LINE/COL ERROR > -------- ----------------------------------------------------------------- > 2/3 PLS-00103: Encountered the symbol "CREATE" when expecting one of > the following: > begin case declare exit for goto if loop mod null pragma > raise return select update while with <an identifier> > <a double-quoted delimited-identifier> <a bind variable> << > close current delete fetch lock insert open rollback > savepoint set sql execute commit forall merge > <a single-quoted SQL string> pipe
Jeśli bardzo tego potrzebujesz, to: execute immediate 'create ...';
Ale tworzenie tabeli tymczasowej w ten sposób nie ma raczej sensu. Podobnie widoku. Po prostu stwórz je raz i korzystaj.
-- Michał Kuratczyk
wk - 02-08-2006 00:48
Użytkownik "Michał Kuratczyk" <kura@lj.pl> napisał w wiadomości news:ealde6$n8d$1@mx1.internetia.pl... > Adam Przybyłek wrote: > > No wlasnie jak probowalem robic tymczasowa w Oracle wewnatrz triggera to > > tez wywalal blad. Oto przyklad: > > .... > > Jeśli bardzo tego potrzebujesz, to: > execute immediate 'create ...'; > > Ale tworzenie tabeli tymczasowej w ten sposób nie ma raczej sensu. Podobnie > widoku. Po prostu stwórz je raz i korzystaj.
Rób, tak jak poradził przedpiśca... W Oraclu jest troche inna "filozofia" niż w PostgreSQLu Tworzysz obiekt - tablice tymczasową - raz (z zewnątrz) i potem tylko uzywasz, czyli wstawiasz tam wiersze (np. w triggerze) Tablica tymczasowa ma te własność, że dane w niej są widziane tylko w jednej sesji i jest jakby dla każdej sesji jej własną wersją (taką można by rzec: zmultiplikowaną, z ograniczeniami integralnościowymi tylko na danych danej sesji) Ale musi być utworzona zewnętrznie (czyli np w SQL'Plusie robisz: "create global temporary table test ..." i jest wtedy stałym obiektem - inaczej niż to się robi zwyczajowo w PostgreSQLu.
-- wk
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[MySQL] =?ISO-8859-2?Q?z=B3=B1czenie_tabeli_u=BFytkownik_i?==?ISO-8859-2?Q?_zdj=EAcia_z_wyborem_zdj=EAcia_domy=B6lnego?=
[MySQL] Jak =?ISO-8859-2?Q?wpisa=E6_do_tabeli_pozycje_dl?==?ISO-8859-2?Q?a_wierszy_gdybym_te_wiersze_wybiera=B3_w_ok?== ?ISO-8859-2?Q?re=B6lonej_kolejno=B6ci_=3F?=
=?ISO-8859-2?Q?Zawarto=B6=E6_tabeli_na_podstawie_warto=B6?==? ISO-8859-2?Q?ci_w_innej?=
[oracle] zapytanie dynamiczne z =?ISO-8859-2?Q?=22dynamiczn=B1_?==?ISO-8859-2?Q?nazw=B1_tabeli=22?=
MySQL - jak =?ISO-8859-2?Q?wyeksportowa=E6_zawarto=B6=E6_wie?==?ISO-8859-2?Q?lkiej_tabeli?=
[MySQL] Skopiowanie =?ISO-8859-2?Q?warto=B6ci_z_jednego_po?==?ISO-8859-2?Q?la_do_drugiego_w_jednej_tabeli=2C_r=F3=BFne_?= =?ISO-8859-2?Q?wiersze=2E?=
Photoshop CS2 - funkcje, =?ISO-8859-2?Q?kt=F3rych_si=EA_nie_?==?ISO-8859-2?Q?spodziewasz=2E=2E=2E?=
=?iso-8859-2?q?[oracle]_Jak_sprawdzi=E6_wielko=B6=E6_tabeli_=3F=3F?=
Liczba =?ISO-8859-2?Q?odpowiadaj=B1cych_rekord=F3w_z_drugi?==?ISO-8859-2?Q?ej_tabeli?=
Oracle PL/SQL Wstawianie =?ISO-8859-2?Q?wynik=F3w_kolekcji_d?==?ISO-8859-2?Q?o_tabeli?=
zanotowane.pldoc.pisz.plpdf.pisz.plnumervin.keep.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|