![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 4 Pomógł: 0 Dołączył: 22.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
Witam,
sprawa ma się następująco: mam dwie tabele o identycznej strukturze:
różnią się tylko nazwą... mam trigger'a który w momencie modyfikacji wiersza/wierszy z pierwszej tabeli poprzednie "wersje" przenosi do drugiej (śledzenie zmian swoiste) pole `ser` które jest w tym przypadku numerem seryjnym nie może zostać w żasdnym przypadku zmodyfikwane... pókico wyprodukowałem coś takiego:
sprawuje się genialnie natomiast jest to app rozwijany ciągle i muszę mieć możliwość dość lekkiego dodawania kolejnych kolumn do tych tabel (w tej chwili jest raptem 20)... zastanawiam się czy można tak opisać tego triggera, żeby: po 1: w przypadku próby zmiany numeru seryjnego zablokował akcję modyfikując tylko pole info lub przywrócił poprzednie wartości wszystkim kolumnom (w tej chwili jest tak to zrobione, jednak jest to o tyle niewygodne, że każde pole muszę osobno wpisać, a chcę tego uniknąć) po 2: wygodniejsze kopiowanie... znowuż w tej chwili muszę wszystkie pola wypisać, bo id jest auto_increment insert into trtest2 select * from trtest2; daje niezbyt przyjemny efekt w postaci dublowania klucza... z góry dzięki za wszelkie propozycje (: |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 1 116 Pomógł: 119 Dołączył: 10.05.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
zamiast TRIGGERA w takim przypadku proponuję napisać ZASADĘ (ang RULE), nadpisującą UPDATE, czyli:
zauważ, że nie ma w `nowym` insercie ani słowa o `ser`, więc nie będzie nadpisany. PS: Ja to robiłem na PostgreSQL nie wiem czy składnia jest poprawna dla MySQL, ewentualnie trochę wg specyfikacji MySQL |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 4 Pomógł: 0 Dołączył: 22.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
mysql chyba niezbyt potrafi coś takiego... poza tym :
- wygląda na to, że rekord nie zostanie wypchnięty d drugiej tabeli - brak przechwycenia informacji o próbie modyfikacji - następuje insert i nowy rekord, a nie faktyczny update... (zapomniałem dodać, że `ser` czyli numer seryjny jest unique i musi być unique w pierwszej tabeli, nie może się zdażyć sytuacja, że będą dwa rekordy z tym samym numerem seryjnym w pierwszej tabeli) - dodatkowo mimo wszystko muszę wypisać kolejno kolumny... czego jak pisałem chciałbym uniknąć... |
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 1 116 Pomógł: 119 Dołączył: 10.05.2005 Skąd: Poznań Ostrzeżenie: (0%) ![]() ![]() |
mysql chyba niezbyt potrafi coś takiego... .. no fakt, też nic na ten temat nie znalazłem (może warto przejść na PostgreSQL?) - wygląda na to, że rekord nie zostanie wypchnięty d drugiej tabeli a dlaczego nie, to jest tylko ON UPDATE więc Twój insert działa dokładnie tak jak działał - brak przechwycenia informacji o próbie modyfikacji nie ma problemu, możesz i tę informację funkcjonalność do roli dopisać, żaden problem - następuje insert i nowy rekord, a nie faktyczny update... (zapomniałem dodać, że `ser` czyli numer seryjny jest unique i musi być unique w pierwszej tabeli, nie może się zdażyć sytuacja, że będą dwa rekordy z tym samym numerem seryjnym w pierwszej tabeli) faktycznie mój błąd, w roli po prostu zmień INSERT (...) na UPDATE (...) SET (...) - dodatkowo mimo wszystko muszę wypisać kolejno kolumny... czego jak pisałem chciałbym uniknąć... hmm tu można się zastanowić nad jedną sprawą, w MySQL jest coś takiego jak SHOW FIELDS (czy tam COLS lub FOR EACH ROW, nie pamiętam dokładnie) a potem poiterować po tego wyniku i odseparować tylko `ser`.. nie wiem czy da radę, nigdy nie próbowałem, może warto pomyśleć Natomiast Twoje podejście ma jedną wadę, co by nie było UPDATE i tak się wykona.. więc jak ktoś by chciał zmienic ser to i tak by się zmienił. Może również rozpatrzysz jedno podejście, tylko znowu nie jestem pewien, czy MySQL da sobie z tym radę 1. Użytkownikowi który łączy się z bazą poprzez skrypt PHP odbierasz prawa UPDATE do tej tabeli 2. Tworzysz widok, składający się tylko z kolumn, różnych od `ser` 3. Tworzysz ROLE lub TRIGGERA, na UPDATE (wiem, wiem, widoków nie można updatować, ale można na nie założyć triggery lub role, na pewno w PostgreSQL, w MySQL musisz sprawdzić tę możliwość) 4. Użytkownik łączący się przez skrypt może tylko wykonywać "UPDATE na WIDOKU", więc odcinasz go od możliwości zniszczenia kolumny `ser` ... nie wiem, czy pomogłem, ale niestety z MySQL zatrzymałem się w rozwoju, od dłuższego czasu go nie używam. Jeśli to nie jest problem to przenieś się na PostgreSQL i te wszystkie wymienione tutaj sprawy na pewno tam załatwisz, Pozdrawiam |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 4 Pomógł: 0 Dołączył: 22.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
nie będę się przesiadał na inny system bazodanowy, którego absolutnie nie znam z tytułu jednej napotkanej niewygody (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg)
dwa... nie mogę się przesiąść... to nie jest domowy projekcik (IMG:http://forum.php.pl/style_emoticons/default/winksmiley.jpg) zastanawiam się jeszcze czy nie dało by się transakcji zatrudnić do obsłużenia tego "przywrócenia" wiersza... z tym, że po raz N-ty musiałbym się przebijać przez doc'sy do mysql'a i ćwiczyć... próbowałem procedurki potworzyć, ale jak zobaczyłem jak mysql marnie sobie radzi z "odgadywaniem" moich intencji to zostawiłem to w cholerę na inny czas... no nic... wątek zostawiam otwarty, a póki co opiszę tego triggera korzystająć z mojego początkowego pomysłu... a i jeszcze jedno... nie mogę zdjąć uprawnienia UPDATE bo to app w phpie naskrobany i jakoś tak nie szczególnie chce mi się bawić w przelogowanie user'a do bazy na konkretne akcje... trigger z tym przechwytem jest tylko po to, żeby ktoś kto nie daj boże ominął zabezpieczenia wewnętrzene appa nie mógł jakiejś dewastacji popełnić za dużej (zamierzam jeszcze parę rzeczy dorzucić do informacji o próbie zmiany numeru seryjnego)... ps: zawsze można php'a zatrudnić do sprawdzenia poprawności wszystkiego, ale wydaje mi się zbyteczne przeżucanie danych mysql<->php po parę razy żeby stwierdzić, że wszystko jest ok... mało wydajne... |
|
|
![]() ![]() |
![]() |
Aktualny czas: 21.09.2025 - 17:29 |