Procedury zapamiętane

0

Witam wszystkich. Z uwagi na fakt, że to mój pierwszy post dwa zdania o mnie. Programuje w Delphi (wcześniej Pascalu) już 12 lat. Ostatnio dużo pod kątem baz danych z uwagi na potrzeby zawodowe (ułatwienia w pracy dla mnie). Chciałbym podzielić się moimi uwagami i moimi rozwiązaniami pewnych spraw oraz zapytać o kilka rzeczy, których nie znalazłem na forum. Bawiłem się bazą Paradox'a, ale niestety jako baza desktopowa ma poważne ograniczenia (przede wszystkim brak transakcyjności, a co za tym idzie nadaje się głównie do zastosowań jednostanowiskowych)
Ostatnio przesiadłem się na Delphi + Firebird i idzie mi całkiem dobrze, ale mam kilka pytań/uwag.
Zatem sprawa dotyczy bazy danych Firebird'a.

  1. Czy używacie procedur zapamiętanych do wyświetlania danych? Chodzi mi o to, że mam program, który działa w sieci rozległej (jak wiadomo wąskie gardło przepustowości) i zastanawiałem się czy robić zapytania wybierające SELECT z kodu programu, czy też wywoływać procedury zapamiętane. Przeczytałem, że te drugie znacznie ograniczają ruch w sieci, a ich wykonanie odbywa się na serwerze (czyli teoretycznie szybciej). Zwracany jest tylko wynik zapytania. Jednakże z mojej obserwacji wynika, że nie ma wielkiej różnicy w szybkości działania operacj wyświetlania danych jeżeli używa się SELECT'a z kodu programu zamiast SELECT'a wywołującego procedurę zapamiętaną. CO WY O TYM SĄDZICIE I JAK (W KTÓRYCH WYPADKACH) STOSUJECUE TEN MECHANIZM? Będę wdzięczny za uwagi w tym temacie? Ja na razie pozostaje za procedurą zapamiętaną.

  2. Jak radzicie sobie z wyświetlaniem rekordów detail dla tabeli master na formatce. Chodzi mi o taką hipotetyczną sytuację. Na jednej formatce mamy dwa DBGridy. Jedne zawiera nagłówki faktur, a drugi pod spodem rekordy będące asortymentem danej faktury (czyli detail dla rekordu master danej faktury).
    Teraz zmieniamy (klikamy) fakturę na inną i powinny w dolnym DBGridzie wyświetlić się rekordy detail dla nowo wskazanej faktury. Gdzie obsługujecie to zdarzenie, żeby zawsze działało (zarówno dla klawiatury jak i myszki oraz innych zdarzeń operujących na rekordach). Ja próbowałem wielu sposobów i znalazłem tylko jeden, który działa za każdym razem. Otóż umieszczam na formatce niewidoczne pole ID tabeli master i obsługuje zdarzenie OnChange dla tego pola. Jeśli wartość się zmieni to ponownie wykonywane jest zapytanie SELECT dla tabeli detail (czyli asortymenty danej faktury). MOŻE JEST JAKIŚ PROSTSZY SPOSÓB?

0
  1. Procedury zapamiętanej używam jedynie wtedy, gdy jej wywołanie w programie pozwoli ograniczyć liczbę zapytań do bazy. Użycie procedury zamiast selecta wg mnie mija się z celem.

  2. O ile nie wykorzystujesz dodatkowego filtrowania danych w detail możesz wykorzystać właściwości MasterSource i MasterFields z Table - dane detail będą ładowane automatycznie po zaznaczeniu rekordu Master.

0

Dzięki za uwagi, ale nasuwa mi się w związku z tym kilka wniosków:
Ad 1. Zauważ, że przy procedurach wyzwolonych cały mechanizm przetwarzania odbywa się na serwerze, a tylko wynik jest wzracany. Teoretycznie powinno być szybciej. Nie sprawdzałem tego przy bardzo dużej liczbie rekordów. Być może wówczas jest jakaś różnica. Gdy SELECT'a utworzy się w kodzie programu, czyli wywołuje ze stacji roboczej to zapytanie jest przygotowywane lokalnie, następnie przesyłane do serwera'a, który ponownie musi je przygotować i odpowiedzieć.
Z drugiej strony jest sporo racji w tym co piszesz chociażby z dwóch powodów :

  1. selecty z różnymi sortowaniami (np. przy wyborze pola sortowania danej tabeli na formatce) w zależności od ustawień skomplikowałyby procedurę zapamiętaną, bo należałoby wpisać ich kilka w zależności od wyboru pól do sortowania (zmieniony select w zależności od sposobu sortowania)
  2. Przeglądałem bazy danych producentów oprogramowania i często widzę w procedurach zapamiętanych Inserty, Delete'y, Update'y, ale nie widziałem procedur do wyświetlania. Zatem coś musi być na rzeczy :)

Ad 2. Używam komponentu TIBQuery a nie TIBTable a w nim nie ma MasterRecord i MasterDetail.
Używałem tych pól z powodzeniem przy Paradox'ie, ale w systemie transakcyjnym nie.

0

Ad 1. Do wyświetlania danych używa się WIDOKÓW(ewentualnie funkcji tabelarycznych*), a nie procedur składowanych. Procedury składowane tworzy się po to, żeby wykonały jakąś operację na bazie danych, a nie zwróciły wynik selecta.

*FB chyba nie ma czegoś takiego jak funkcja tabelaryczna

Po co stosować widoki?

Załóżmy, że w aplikacji wyświetlasz:

SELECT * FROM tabela

Bez sensu stosować widok.

SELECT t1.pole, t1.pole2, ..., t2.pole, t2.pole2
FROM tabela t1
left join tabela2 t2 on t2.TID = t1.ID

Tu już się można pokusić o widok, chociaż to zależy właściwie od tego, ile razy ten kod wykorzystujesz w programie, w bazie i od Twojego widzimisię.

Natomiast przy większej ilości joinów NALEŻY stosować widoki. Dlaczego? Załóżmy, że kod stosujesz 2 razy w aplikacji i 5 razy w bazie(np. w procedurach składowanych). I przyszedł czas na zmianę. Bez widoków musisz zmienić ten kod w 7 miejscach(dodatkowo możesz o czymś zapomnieć). Z użyciem widoków zmieniasz tylko widok.

Sprawę prędkości pomijam, bo przy takich operacjach, raczej nie ma żadnego wpływu. Rzecz jasna, operacje wykonywane na serwerze zawsze będą szybsze.

Ad 2. Drugie pytanie wcale nie dowodzi, że programujesz w Delphi lat 12 :D
W każdym razie masz na datasecie takie zdarzenie jak AfterScroll. Zachodzi podczas zmiany aktywnego rekordu. Oczywiście oprócz pól widocznych zawsze dodawaj niewidoczne pole ID. Tak samo, jak zawsze w każdej tabeli twórz pole ID, które będzie pełniło rolę identyfikatora.

I teraz, w zdarzeniu AfterScroll górnego dataseta wywołujesz jakąś metodę w stylu: "RefreshView(false, true)", gdzie parametry oznaczają, który grid odświeżyć(górny, dolny). Dalej chyba wiadomo.
No przynajmniej ja tak to robię.

0

Z IBQuery też się da - ustawiasz mu master source a w selekcie po prostu piszesz where pole = :pole_z_zapytania_master (albo jakoś podobnie - dawno tego nie używałem)

Co do SP to czy w query bedziesz miał select a, b, c, d from tabela czy select a, b, c, d from procedura to, za przeproszeniem jeden h**. Jedyny narzut jest taki, że musisz przesłać jeszcze warunek, ale miałeś kiedyś zapytanie, które by zajmowało 1MB (chodzi o tekst)?
Natomiast insert, update, delete w SP służy generallnie do ograniczenia dostępu do danych a nie zmniejszenia ruchu - nie musisz dać userowi uprawnień do insert, update, delete a jedynie do wykonywania SP, w których możesz kontrolować dodatkowo co jest usuwane, zmieniane itp

Inna sprawa odnośnie SP to takie, które np. przed jednym insertem muszą zrobić kilka(naście)(dziesiąt) zapytań i obrobić ich wynik

0
  1. Nie mam pojęcia w jakiej postaci zapytanie przesyłane jest do serwera ale nie sądzę, żeby to miało istotny wpływ na wydajność aplikacji. Co to znaczy, że zapytanie jest przygotowywane lokalnie? Zbiór wyników przesyłany do klienta jest w obu przypadkach identyczny (jak sądzę).

  2. Proponuję zdarzenie AfterScroll dla Query.

0

Juhas : no cóż, człowiek uczy się całe życie :) Tak jak pisałem programuje długo w Delphi, ale od pewnego czasu bawie się z bazami danych. Tak poważnie to faktycznie przeoczyłem zdarzenie AfterScroll, które może być ciekawą alternatywą i niezłocznie spróbuje to sprawdzić, Dzięki.
Co do kilkakrotnego poprawiania kodu, gdy wywołuje się go w wielu miejscach to faktycznie spora racja, bo zawsze należy dążyć do minimalizacji kodu. Tutaj procedury zapamietane bardzo się przydają.

Misiekd : Sprawa uprawnień wydaje się zasadna tylko tutaj dotykam innej sprawy. Otóż jeśli ktoś ma dostęp do bazy danych to i tak może ją przenieść na inny komputer gdzie SYSDBA będzie miał standardowe hasło i pełne uprawnienia i nici. Z tego co wyczytałem nie ma bowiem możliwości wyłączenia lub ograniczenia SYSDBA na rzecz tworzonych przez siebie użytkowników.
Powtarzam jeśli ktoś ma dostęp fizyczny do pliku bazy!

Ciesze się z Waszych wypowiedzi, bo utwierdzam się w przekonaniu, że jednak spróbuje używać SELECTów do wyświetlania danych z kodu programu, a nie jako procedury zapamietane. Dobrze posłuchać praktyków.

0
witrz napisał(a)

Misiekd : Sprawa uprawnień wydaje się zasadna tylko tutaj dotykam innej sprawy. Otóż jeśli ktoś ma dostęp do bazy danych to i tak może ją przenieść na inny komputer gdzie SYSDBA będzie miał standardowe hasło i pełne uprawnienia i nici. Z tego co wyczytałem nie ma bowiem możliwości wyłączenia lub ograniczenia SYSDBA na rzecz tworzonych przez siebie użytkowników.
Powtarzam jeśli ktoś ma dostęp fizyczny do pliku bazy!

prawda, ale świat nie kończy się na FB :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1