Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> trigger na tej samej tabeli
nospor
post
Post #1





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Mam procedurę, ktora zmienia mi wartosc pola POLE na 4, ale tylko dla tych rekordów, których mają aktualnie wartosc pola 3.

Teraz przy UPDATE pola wywoluje trigger (before), ktory wykonuje mi powyższą procedurę, ale tylko wowczas, gdy nowa wartosc pola to 3. Czyli defacto nie ma zapętlenia żadnego, jednak oracle nie pozwala na takie numery. Czy mozna jakos trigger wywolac by lał na to i dzialał? Bo teraz oracle tak jakby podejrzewa ze moze byc zapetlenie, gdyz wywoluje trigger, a w nim wywoluje procedure ktora znowu mi ten sam trigger wzbudza. Jednak ten trigger z procedury nie wywola zadnych zmian, gdyz nowa wartosc pola to 4 nie 3.
Jak ktos zalapal oco biega i jakims cudem zna rozwiązanie to bardzo prosze o cynk.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
KILIUSZKIN
post
Post #2





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 26.01.2006

Ostrzeżenie: (0%)
-----


Znalazłem taką korespondecję :

1.)
We have a table with a key1, key2, figure1, calcul1 fields.

What I want to do is an update trigger that when a row is updated or a new
one is inserted that it calculates the calculated field calcul1 dpending
on other row in that table.

But what happens? As the lines is updated oracle starts the trigger and
updates the calculated field, so the row is again updated and it starts
again the trigger or is that a wrong consumption?

Ad 1.)
It is a wrong assumption.
Actually Oracle keeps 2 sets of row values in memory
and you update in trigger the :new set of values ( if
it is BEFORE trigger ).
On the other hand - Oracle will not allow you to execute
a trigger that access the same table which is currently
updated ( See MUTATING TABLE in APPLICATION
DEVELOPER's GUIDE ).
There is a nice solution in Oracle 8.x -
using INSTEAD OF trigger on VIEW during the update.
In Oracle 7.x - you must use temp. table / PL/SQL tables
and AFTER STATEMENT triggers to bypass it.

Sam niestety INSTEAD OF trigger on VIEW jeszcze nie używałem..... guitar.gif
Może to Ci pomoże winksmiley.jpg

Ten post edytował KILIUSZKIN 6.12.2006, 12:44:02


--------------------
________________________________________________________________________________
czy programiści używają jeszcze diagramów ? jeśli nie, to tylko zwykli koderzy są ;)
Go to the top of the page
+Quote Post
nospor
post
Post #3





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




hmmm, ale to musze widok dodatkowy tworzyc?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
php programmer
post
Post #4





Grupa: Zarejestrowani
Postów: 1 045
Pomógł: 5
Dołączył: 8.11.2004
Skąd: trójmiasto

Ostrzeżenie: (0%)
-----


Troche głupie, ale może w triggerze
zamiast zapytania UPDATE tabela SET ...
zrobić zapytanie DELETE a potem INSERT

Ten post edytował php programmer 6.12.2006, 13:48:31
Go to the top of the page
+Quote Post
nospor
post
Post #5





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




@php programmer hehe, no jest to pewne rozwiązanie, a moze nie - nie rozwiązanie, ale bardzo nieeleganckie obejscie sprawy.

No ale i tak nie mozna, gdyz na tabeli mam relacje, i jesli cos usuwam, to leci razem z nią rekordy z innych tabel, takze klops. Pozatym tamten trigger ja mam na update/insert, wiec sytuacja by sie powtorzyla


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
php programmer
post
Post #6





Grupa: Zarejestrowani
Postów: 1 045
Pomógł: 5
Dołączył: 8.11.2004
Skąd: trójmiasto

Ostrzeżenie: (0%)
-----


Mam,

tworzysz sobie drugą tabele (która nie zawiera zadnych potrzebnych danych),
robisz Triggera że jak zmieni pierwszą to robi jakiś
tam bezsensowny UPDATE natej drugiej,
i zakladasz drugiego Trigera robiącego UPDATe na pierwszej w momencie UPDATE na tej operacyjnej,

Zresztą UPDATE na tej operacyjnej wcale nie musi być bezsensowny,
mozesz sobie ustalić jakieś konkretne operacje UPDATE tak
aby tabela operacyjna obsługiwała takzeinne tabele
(czyli w zalezności od UPDATE rozpoznajesz o ktora tabele ci chodzi)

poza tym tabela operacyjna moze byc też czymś w rodzaju historii

Ten post edytował php programmer 6.12.2006, 13:59:08
Go to the top of the page
+Quote Post
nospor
post
Post #7





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




dzieki, ale ja wlasnie chcialem uniknac tworzenia dodatkowych tabel tudziez widokow. Ale najwyraźniej w tej "genialnej" bazie sie nie da.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
php programmer
post
Post #8





Grupa: Zarejestrowani
Postów: 1 045
Pomógł: 5
Dołączył: 8.11.2004
Skąd: trójmiasto

Ostrzeżenie: (0%)
-----


OK jeszcze jedna próba,
nie wiem czy to sie da w ogóle tak zrobić, ale
moze wywołać wTrigerze jakąs funkcję
ktora dopiero robi taki UPDATE
Go to the top of the page
+Quote Post
nospor
post
Post #9





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




no i ja wlasnie tak mam: w trigerze wywoluje procedure, w ktorej to dopiero jest robiony update smile.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
php programmer
post
Post #10





Grupa: Zarejestrowani
Postów: 1 045
Pomógł: 5
Dołączył: 8.11.2004
Skąd: trójmiasto

Ostrzeżenie: (0%)
-----


To może fukcja wywołana przez trigger zamist wykonac UPDAT wywoła
koleną funkcję która dopiero wykona UPDATE,

a tak wogóle to ORACLE musi mieć w swoim FAQ
taki problem poruszony, przeciez takie TRIGGERY są bardzo często

Ten post edytował php programmer 6.12.2006, 14:20:42
Go to the top of the page
+Quote Post
nospor
post
Post #11





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




hehe, nie. niezaleznie ile tych funkcji bedziesz mial to bedzie to samo smile.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Synaps
post
Post #12





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 1.12.2003
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


Nie wiem czy dobrze zrozumiałem :
- UPDATE danych nigdy nie pozwoli na ustawienie w POLU wartości "3"
- próba UPDATE'u na 3 spowoduje zmianę wszystkich rekordów w tabeli gdzie POLE=3 na POLE=4
- jedyny sposób aby w tabeli znalazł się rekord gdzie POLE=3 jest INSERT

Może problem leży we wcześniejszym zaprojektowaniu tego rozwiązania, ponieważ jeśli nie chcesz aby ktoś zmieniał POLA na wartość 3 oraz jeśli nastąpi taka próba zmieniasz wszystkie rekordy , to może zrezygnować w ogóle z możliwości wstawienia w tym polu 3 ( bazuj tutaj na tym co zrozumiałem ) ;-)

Co do wywołania w triggerze procedury/funkcji która modyfikują tą samą tabele- to rzeczywiście Oracle na to nie pozwoli.


--------------------
MySQL said:

You have an error in your SQL syntax near ' `sygnatura` VARCHAR, NOT NULL
Go to the top of the page
+Quote Post
nospor
post
Post #13





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
UPDATE danych nigdy nie pozwoli na ustawienie w POLU wartości "3"
czemu nie pozwoli? pozwoli smile.gif ja bede modyfikowal statusy. Chodzilo oto, ze procedura, ktora wywoluje trigger, zmienia status tylko na 4 a nigdy na 3. Ona zmienia z 3 na 4. Tak wiec bazka jest zaprojektowana ok. Jest to standardowa sytuacja, gdy mozesz miec cos opublikowanego. W danej chwili jednoczesnie moze byc ttlko jedna rzecz opublikowana (status=3). Gdy pojawia sie cos nowego do publikacji (cos dostaje status 3), to co bylo opublikowane przechodzi do archiwum (status 3 w innych rekordach zmienic na 4).

Cytat
Co do wywołania w triggerze procedury/funkcji która modyfikują tą samą tabele- to rzeczywiście Oracle na to nie pozwoli.
no i to juz wiemy winksmiley.jpg


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Synaps
post
Post #14





Grupa: Zarejestrowani
Postów: 103
Pomógł: 0
Dołączył: 1.12.2003
Skąd: Gdynia

Ostrzeżenie: (0%)
-----


OK, skoro twierdzisz że logika jest poprawna , spróbuje podać Ci sposób aby wprowadzić ten plan w życie cool.gif
Będzie trochę skrótów , ale mam nadzieje że sobie poradzisz, w razie czego postaram się pomóc.

Do rzeczy :

1) Stwórz pakiet z dwoma procedurami :
- dodanie do listy (np add_to_list )
- zatwierdzenie zmian ( np save )

Aby zapewnić pojedyńcze i mass update'y najlepiej zadeklarować w pakiecie tablice, która będzie zawierać pola , dzięki którym będzie można dokładnie określić rekord w tabeli. Już tłumacze - tablica ta będzie wykorzystywana do 'zapamiętania' modyfikowanych rekordów ( 'zapamiętywać' będzie pierwszy trigger 'A'), następnie na jej podstawie trigger 'B' ;-) dokona modyfkacji.

2) Stwórz trigger na tabeli
  1. CREATE OR REPLACE TRIGGER DUMMY_TBL_A_TRG
  2. AFTER INSERT OR UPDATE
  3. ON DUMMY_TBL
  4. REFERENCING NEW AS NEW OLD AS OLD
  5. FOR EACH ROW


W kodzie zaimplementuj 'zapamiętywanie' np
  1. ...
  2. moj_pakiet.add_to_list(:NEW.id_pola,:new.pole);
  3. ...


3) Stwórz drugi trigger, tutaj już podam pełny przykład

  1. CREATE OR REPLACE TRIGGER DUMMY_TBL_B_TRG
  2. AFTER UPDATE ON DUMMY_TBL
  3. BEGIN moj_pakiet.save;
  4. END;



Jak łatwo się domyśleć procedura SAVE powinna zawierać sprawdzanie warunków i update tabeli DUMMY_TABLE.

Na koniec małe wyjaśnienie i ostrzeżenie aaevil.gif Rozwiązując ten problem wykorzystujemy właściwość pakietów - w obrębie sesji zmienne pakietowe są wspólne , dzięki czemu jeden trigger zapamiętuje rekordy a drugi dokonuje ich modyfikacji. Jednak niesie to ze sobą pewne niebezpieczeństwo - należy pamiętać aby w odpowiednim momencie wyczyścić tabele która zapamiętuje rekordy (jeśli istnieje taka potrzeba ) - można to zrobić np w dodatkowych triggerze BEFOR UPDATE.

Ten post edytował Synaps 12.12.2006, 03:11:23


--------------------
MySQL said:

You have an error in your SQL syntax near ' `sygnatura` VARCHAR, NOT NULL
Go to the top of the page
+Quote Post
Sedziwoj
post
Post #15





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(nospor @ 6.12.2006, 16:12:36 ) *
czemu nie pozwoli? pozwoli smile.gif ja bede modyfikowal statusy. Chodzilo oto, ze procedura, ktora wywoluje trigger, zmienia status tylko na 4 a nigdy na 3. Ona zmienia z 3 na 4. Tak wiec bazka jest zaprojektowana ok. Jest to standardowa sytuacja, gdy mozesz miec cos opublikowanego. W danej chwili jednoczesnie moze byc ttlko jedna rzecz opublikowana (status=3). Gdy pojawia sie cos nowego do publikacji (cos dostaje status 3), to co bylo opublikowane przechodzi do archiwum (status 3 w innych rekordach zmienic na 4).

no i to juz wiemy winksmiley.jpg

Czyli w tabeli masz zawsze tylko jedno pole POLE o wartości równej 3?
Czyli tak właściwie tylko zmieniasz jedno pole POLE z 3 na 4, pomijając fakt że na pewno będziesz chciał móc wybierać co jest wyświetlane. Chyba że tylko nowe INSERT rzeczy będą mieć 3 a w UPDATE zakażesz tego i w DELETE jeśli kasujesz to też musisz zmienić w którymś wartość pola POLE z 4 na 3 aby zawsze było coś wyświetlane (chyba że nie musi być zawsze).

Chociaż moim zdaniem dziwne to całkowite blokowanie, powinno dać się wyłączyć aby jak ktoś jest pewien kodu aby to zrobiła lae to chyba podejście aby baza była stabilna biggrin.gif

Hmm, przy UPDATE wywołujesz Triggera która przy znalezieniu POLE=3 wywołuje UPDATE a jak już robisz UPDATE to znów się wywołuje Triggera który się zapętla. Czy może ja źle myślę questionmark.gif

EDIT: Mylę się w ostatnim akapicie bo nie zawsze jest wywoływane UPDATE a jak jest to tylko ze zmianą POLE=4 więc nie wywołuje kolejny raz funkcji.

Tak mnie to gryzie, więc napiszę po co Ci właściwie to pole POLE?
Przecież wystarczy mieć tabele która przechowuje aktualnie wyświetlany rekord, a tak masz x-1 nadmiarowych pól?! (bo przecież każde POLE=4 jest nadmiarowe)

Ten post edytował Sedziwoj 11.12.2006, 17:06:30


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
nospor
post
Post #16





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




@Synaps wow smile.gif
Sek w tym, ze chcialem uniknac dodatkowych tabel, a u Ciebie z tego co czytam, to istnieje jedna dodatkowa. Ale dzieki.

@Sedziwoj a czytajac Twojego posta to przez chwila zdurnialem i juz sam niemoglem dojsc oco mi chodzi winksmiley.jpg
Wydaje mi sie, ze jasno tu to opisalem:
Cytat
W danej chwili jednoczesnie moze byc ttlko jedna rzecz opublikowana (status=3). Gdy pojawia sie cos nowego do publikacji (cos dostaje status 3), to co bylo opublikowane przechodzi do archiwum (status 3 w innych rekordach zmienic na 4).
Jasniej juz sie nie da.


Cytat
Tak mnie to gryzie, więc napiszę po co Ci właściwie to pole POLE?
Przecież wystarczy mieć tabele która przechowuje aktualnie wyświetlany rekord, a tak masz x-1 nadmiarowych pól?! (bo przecież każde POLE=4 jest nadmiarowe)
questionmark.gif
Po co mi tabela co bedzie trzymala tylko jeden rekord? U mnie tabela trzyma rekordy, kazdy z nich moze byc w roznym stanie, kazdy rekord moze w kazdej chwili zmienic swoj stan. O jakim nadmiarze mowisz?


Podsumowujac:
olalem triggery, bo widze ze na oraclu bez dodatkowych tabel/widokow sie nie obejdzie. To co mial robic trigger robie "recznie" w php.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Sedziwoj
post
Post #17





Grupa: Zarejestrowani
Postów: 793
Pomógł: 32
Dołączył: 23.11.2006
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


Cytat(nospor @ 11.12.2006, 18:17:01 ) *
@Sedziwoj a czytajac Twojego posta to przez chwila zdurnialem i juz sam niemoglem dojsc oco mi chodzi winksmiley.jpg
Wydaje mi sie, ze jasno tu to opisalem:
Jasniej juz sie nie da.
questionmark.gif
Po co mi tabela co bedzie trzymala tylko jeden rekord? U mnie tabela trzyma rekordy, kazdy z nich moze byc w roznym stanie, kazdy rekord moze w kazdej chwili zmienic swoj stan. O jakim nadmiarze mowisz?

Jak na razie widzę, że POLE ma dwa stany 3 i 4 więc oprócz jednego reszta ma 4. Więc dodawanie jednego pola tylko aby oznaczyć jeden rekord jest dla mnie bez sensu.
Co do stanów przecież tylko jeden ma inny, to wynika z Twojej wypowiedzi i nic ponadto, że mogę się domyślać że oprócz stanu 3 i 4 może istnieć inny stan.
Tu chodzi o podejście, w jednych tabelach masz tylko dane z identyfikatorami inne łączą je.
Nie wiem czy tworzenie tabeli z jednym rekordem i do tego jedno polowym ma sens ale mniejszy ma dla mnie tworzenie nowego pola dla każdego rekordu gdy potrzeba tylko jeden wskazany.
Przyznam projektowanie baz danych nie należy u mnie do rzeczy dobrze opanowanych ale nadal w tej podanej sytuacji nie widzę sensu umieszczani pola POLE tym bardziej że przy każdym dodaniu nowego przeszukuje całą tabele i to samo przy edycji a jak byś miał jedną dodatkową tabelę z jednym polem to tyko odczyt jednego jedynego rekordu czy modyfikacja to nie koszt.

Ale już nie będę się kłócił, bo równie dobrze się mogę mylić, ale chyba w Oracle by nie blokowali czegoś co jest użyteczne...


--------------------
Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami.
Go to the top of the page
+Quote Post
nospor
post
Post #18





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Jak na razie widzę, że POLE ma dwa stany 3 i 4 więc oprócz jednego reszta ma 4. Więc dodawanie jednego pola tylko aby oznaczyć jeden rekord jest dla mnie bez sensu.

Ja tylko opisalem te dwa stany, bo tylko one byly potrzebne do przedstawienia problemu. Stanow jest 5: 1,2,3,4,5 smile.gif
A nawet jakby byly tylko te dwa, to robienie oddzielnej tabeli by wykluczyc jedno pole i trzymac w tej oddzielnej tabeli ten jeden rekord to by bylo nieteges winksmiley.jpg.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
KILIUSZKIN
post
Post #19





Grupa: Zarejestrowani
Postów: 45
Pomógł: 0
Dołączył: 26.01.2006

Ostrzeżenie: (0%)
-----


Nie wiem czy to zadziała (jutro jak będę miał czas to sprawdzę), ale możesz w triggerze
BEFORE UPDATE przed wywołaniem Twojej procedury dodać:
1. alter trigger nazwa_triggera disable;
tutaj wywołanie Twojej procedury--------
a następnie
2. alter trigger nazwa_triggera enable;

GOOD NIGHT ALL ORACLE FANS OR NOT guitar.gif


--------------------
________________________________________________________________________________
czy programiści używają jeszcze diagramów ? jeśli nie, to tylko zwykli koderzy są ;)
Go to the top of the page
+Quote Post
nospor
post
Post #20





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




@KILIUSZKIN a wiesz że juz to probowalem zrobic smile.gif
ale cos mnie nie wychodzilo sad.gif
albo ja tylko sie przymierzalem by to zrobic ale nie zdązylem bo zasnalem.... albo jedno albo drugie. tak czy siak pokasowalem juz te triggery i procedury i niechce mi sie juz do tego wracac.

edit: aczkolwiek sprawdź tak jak mowiles. jesli ci to zadziala to napewno sie przyda na przyszlosc.
Ale czy to rozwiązanie nie niesie pewnego ryzyka? Gdy procedura wywali blad, wowczas linijki z enable nie wykona sie. Mozna by ewentualnie wychwytywac wyjatek i po wychwyceniu wykonac enable i potem przekazac dalej ten wyjatek


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 16:08