znaczacy > comp.* > comp.bazy-danych

Marek S (04.11.2019, 00:18)
Witam Was,

Mam klopot ze zrozumieniem, co sie dzieje. Otóz stworzylem trigger:

CREATE OR REPLACE FUNCTION admin.category_delete()
RETURNS TRIGGER AS
$$
BEGIN
RAISE NOTICE 'Weight %, parent ID %', OLD.weight,
OLD.parent_id;
UPDATE admin.category SET weight = weight - 1 WHERE
parent_id = OLD.parent_id AND weight > OLD.weight;
RAISE NOTICE 'After update';
RETURN OLD;
END;
$$
LANGUAGE plpgsql;

Wywoluje go jako:

CREATE TRIGGER category_delete AFTER DELETE ON admin.category FOR EACH
ROW EXECUTE PROCEDURE admin.category_delete()

No i update z niego nie jest realizowany. Zachowuje sie tak jakby byl
zakomentowany. W logach bazy sa linie to sugerujace:

2019-11-03 23:06:01.946 CET [13200] DZIENNIK: wyraĹĽenie: BEGIN
2019-11-03 23:06:01.947 CET [13200] DZIENNIK: wykonanie <unnamed>:
DELETE FROM admin.category WHERE category_id = $1
2019-11-03 23:06:01.947 CET [13200] SZCZEGĂā€œÄ¹ĀY: parametry: $1 = '1'
2019-11-03 23:06:01.950 CET [13200] UWAGA: Weight 1, parent ID <NULL>
2019-11-03 23:06:01.950 CET [13200] KONTEKST: funkcja PL/pgSQL
admin.category_delete(), wiersz 3 w RAISE
2019-11-03 23:06:01.950 CET [13200] UWAGA: After update
2019-11-03 23:06:01.950 CET [13200] KONTEKST: funkcja PL/pgSQL
admin.category_delete(), wiersz 5 w RAISE
2019-11-03 23:06:01.951 CET [13200] DZIENNIK: wyraĹĽenie: COMMIT

Powstaja informacyjne exceptions przed wykonaniem aktualizacji i po.
Natomiast nie ma sladu po tym, co jest miedzy komunikatami. O co chodzi?
irq (04.11.2019, 17:19)
W dniu niedziela, 3 listopada 2019 23:18:09 UTC+1 uzytkownik Marek S napisal:

> No i update z niego nie jest realizowany. Zachowuje sie tak jakby byl
> zakomentowany. W logach bazy sa linie to sugerujace:


LOG nie pokazuje statementów wykonywanych z wnetrza funkcji. Nie oznacza to, ze "update z niego nie jest realizowany".

Jezeli rzeczywiscie chcesz podgladac w logu, czy dochodzi do updatu, zalóz sobie, na przyklad, trigger ON UPDATE na tej tabeli i tam umiesc stosowny RAISE NOTICE.
Marek S (04.11.2019, 22:56)
W dniu 2019-11-04 o 16:19, irq pisze:
> Jezeli rzeczywiscie chcesz podgladac w logu, czy dochodzi do updatu,
> zalóz sobie, na przyklad, trigger ON UPDATE na tej tabeli i tam
> umiesc stosowny RAISE NOTICE.


Sprytne. Dzieki ;-)

Kiedys istnial debugger dla funkcji skladowych. Znalazlem jedynie zródla
w jezyku C do niego. Dla mnie bezuzyteczne - nie zajmuje sie
programowaniem w C. Czy orientujesz sie gdzie mozna znalezc skompilowany
plugin?

A moze masz inne sugestie na temat tego jak debugowac w/w? Zakladanie
trigerów debugingowych jest dosc klopotliwe.
Marek S (04.11.2019, 23:45)
W dniu 2019-11-04 o 16:19, irq pisze:

> LOG nie pokazuje statementów wykonywanych z wnetrza funkcji. Nie
> oznacza to, ze "update z niego nie jest realizowany".


Znalazlem powód niedzialania update. Rozwiazalem go tak:

IF OLD.parent_id ISNULL THEN
UPDATE admin.category SET weight = weight - 1 WHERE parent_id ISNULL
AND weight > OLD.weight;

ELSE
UPDATE admin.category SET weight = weight - 1 WHERE parent_id =
OLD.parent_id AND weight > OLD.weight;

END IF;

Nie dziala porównanie parent_id = OLD.parent_id jezeli wartosc jest
nullem. Uswiadomilem sobie, ze OLD.parent nie jest czescia SQL lecz
zmienna, której wartosc wstawiamy, wiec parent_id = null nie moze
zadzialac. :-)

Czy orientujesz sie czy istnieje jakis trik umozliwiajacy unikanie
nadmiarowych warunków w funkcjach? Mam na mysli "legalne" triki.
irq (05.11.2019, 13:12)
W dniu poniedzialek, 4 listopada 2019 22:45:13 UTC+1 uzytkownik Marek S napisal:
[..]
> --
> Pozdrawiam,
> Marek


Moze w pierwotnej wersji updata:

WHERE parent_id IS NOT DISTINCT FROM OLD.parent_id

?
Andrzej Strózynski (05.11.2019, 13:46)
W dniu 2019-11-03 oĀ 23:18, Marek S pisze:
[..]
> Wywoluje go jako:
> CREATE TRIGGER category_delete AFTER DELETE ON admin.category FOR EACH
> ROW EXECUTE PROCEDURE admin.category_delete() [...]


Robisz UPDATE wiersza po jego usunieciu?
Marek S (06.11.2019, 21:08)
W dniu 2019-11-05 oĀ 12:46, Andrzej Strózynski pisze:
> Robisz UPDATE wiersza po jego usunieciu?


Robie Update wielu wierszy po usunieciu jednego z nich :-D
Adam M (06.11.2019, 22:54)
On Wednesday, November 6, 2019 at 2:08:59 PM UTC-5, Marek S wrote:
> W dniu 2019-11-05 oĀ 12:46, Andrzej Strózynski pisze:
> > Robisz UPDATE wiersza po jego usunieciu?

> Robie Update wielu wierszy po usunieciu jednego z nich :-D
> --
> Pozdrawiam,
> Marek


Wkladanie logiki biznesowej na triggery to bardzo niebezpieczna zabawa- takie rozwiazania stosowalo sie epoce SQLa lupanego ;-) - prosciej i bezpieczniej przeniesc logike na middleware..
Marek S (07.11.2019, 21:06)
W dniu 2019-11-06 oĀ 21:54, Adam M pisze:

> Wkladanie logiki biznesowej na triggery to bardzo niebezpieczna zabawa - takie rozwiazania stosowalo sie epoce SQLa lupanego ;-) - prosciej i bezpieczniej przeniesc logike na middleware.


Tak, wiem, ze niebezpieczna. Dlatego 15x to testuje zanim udostepnie.

Owszem, obecnie zwykle przenosi sie logike tego typu do ORMów, a nawet
widzialem raz sortowanie wykonane w PHP (!!!) w imie przenoszenia
wszystkiego, co mozliwe do wykonania na bazie poza nia. Zauwazam, ze
zapanowala wielka awersja do uzywania baz danych. Zdarza sie nawet, ze
obiekty danych trzyma sie w formie plików na dysku (patrz Pimcore). Ja
jednak bede trzymal sie w/w rozwiazan. Wlasnie jestem swiadkiem poczatku
upadku sporego przedsiewziecia - przed czym, u zarania projektu,
przestrzegalem team. Oni slepo ufaja nowoczesnym rozwiazaniom, jakie
proponujesz. W efekcie, przy ok 25 mln rekordów w bazie, niektóre proste
operacje potrafia trwac po kilka minut (klient tyle musi czekac na
response interfejsu) zamiast kilkadziesiat milisekund. Przenoszenie
projektu na super wydajne serwery (hosting pare tys. $), stosowanie
loadbalacera - odsunelo problem w czasie. Osobiscie wygodny ORM stosuje
tylko tam, gdzie nie moze zaszkodzic bardzo: chyba tylko obsluga
formularzy. Zaczynam przenosic rozwiazania nowoczesne, na lupany SQL i
juz w tej chwili zyskuje min. trzy rzedy wielkosci krótsze czasy
realizowanych operacji.

Jednakze mimo wszystko nie zgodze sie z Toba, ze stosowanie procedur
skladowych w bazie to przestarzale podejscie. Wrecz przeciwnie: widuje w
korporacjach dzialy administratorów baz danych, którym wrecz zleca sie
realizowanie procedur skladowych, z których korzystaja programisci.
Programisci nie musza byc swiadomi nawet tego, ze jakas kolumne
przeniesiono z jednej tabeli do innej.
Adam M (07.11.2019, 22:19)
On Thursday, November 7, 2019 at 2:06:10 PM UTC-5, Marek S wrote:
[..]
> --
> Pozdrawiam,
> Marek


Moze troche zaprzecze wlasnemu stwierdzeniu alz zgodze sie z kolega jezeli takie rozwiazanie jest stosowane na bazie Oracle , Sybase ASE lub nawet Microsoft SQL gdzie debugowaniekodu SQL po strownie serwera jest latwe i przyjemne - mozna wtedy traktowac server SQL jak middleware. Niestety PostgrSQL ma fatalny debugger - ostatni jaki uzywalem byl na 9.3 i padal jesli tylko sie na niego czlowiek zle popatrzyl nie mówiac o jakim kolwiek sensownym debugowaniu. Moze cos poprawili na 10 - nie wiem tego bo poprostu sobie odpuscilem debugowanie na PostgreSQL is jesli musze cos pisac to omijam logike na triggerach jak zaraze - procedury skladowane tak (pomimo ze i tak sa skopane na PostgreSQL - nie mozna miec transakcji czesciowych w srodku procedury/funkcji) - logika na triggerach nie - przynajmniej na PostgreSQL.

Pozdrawiam
Adam M
Marek S (08.11.2019, 00:34)
W dniu 2019-11-05 oĀ 12:12, irq pisze:
> Moze w pierwotnej wersji updata:
> WHERE parent_id IS NOT DISTINCT FROM OLD.parent_id
> ?


Tez tak uznalem i chyba przy tym pozostane. Dzieki za sugestie.
Marek S (08.11.2019, 00:56)
W dniu 2019-11-07 o 21:19, Adam M pisze:

> Niestety PostgrSQL ma fatalny debugger - ostatni jaki
> uzywalem byl na 9.3 i padal jesli tylko sie na niego czlowiek zle
> popatrzyl nie mówiac o jakim kolwiek sensownym debugowaniu.


No wiec wlasnie... to tez dla mnie udreka. Popelnie drobny blad (jak w
watku) i mecze sie z nim. Nawet jesli jest oczywisty, swieci jak
latarnia morska, to autosugestia zakazuje dostrzegania go. Trzeba po
omacku dochodzic przyczyn.

> Moze cos
> poprawili na 10 - nie wiem tego bo poprostu sobie odpuscilem
> debugowanie na PostgreSQL


Szczerze - nawet nie mam pojecia. Stosuje 11 i 12 lecz nie wydaje mi sie
by w tym wzgledzie ktokolwiek zadzialal.

> na triggerach jak zaraze - procedury skladowane tak (pomimo ze i tak
> sa skopane na PostgreSQL


Sek w tym, ze lepszy Postgres niz smieciowe MariaDB lub stary MySQL,
który zreszta zdechl. Za inne trzeba czasem srogo placic. Wiec z uwagi
na istniejacy rynek, musze stosowac darmowe rozwiazania. A PostgreSQL
sprawuje sie swietnie, dziala wydajnie nawet przy przyrostach rzedu pól
miliona rekordów dziennie (po paru latach). MySQL (InnoDB) dawno by
odlecial. Stad wybór i raczej bede przy nim tkwil.

> - nie mozna miec transakcji czesciowych w
> srodku procedury/funkcji) - logika na triggerach nie - przynajmniej
> na PostgreSQL.


Mozna mozna i to od dawna ;-)



Czemu logika na trigerach nie? Bo trudno debugowac? To tylko wydluza
developement (bo narzedzie debugingowe kiepskie) lecz nie obniza
wydajnosci rozwiazania. Stosuje od lat tego typu podejscie i jakos nigdy
sie na nim nie przejechalem. Malo tego, powiem Ci, ze pracowalem w
firmie obslugujacej wierzytelnosci (ogromne ilosci wrazliwych danych -
drobny blad danych prowadzilby do kolosalnych strat), która od lat tak
dziala i baza sprawuje sie u nich swietnie. Szczerze - nie mialbym sie
do czego przyczepic.
Podobne w±tki