Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Trigger dla INSERT.. problem składniowy
Forum PHP.pl > Forum > Bazy danych > MySQL
mikajlo
Witam,
jestem początkującym samoukiem i potrzebuję utworzyć trigger, który po wstawieniu danych do tabeli T1, wstawi jedną z wstawionych wartości do tabeli T2.
Z tym, że jeśli wartość ta jest null albo "" (czyli defacto pusta) ma nie wykonywać inserta..

Akutalnie wygląda to tak:

  1.  
  2. DELIMITER $$
  3. CREATE TRIGGER insertClub AFTER INSERT ON users
  4. FOR EACH ROW BEGIN
  5. SET @var = NEW.clubUser;
  6. IF (@var IS NOT NULL OR @var <> '') THEN
  7. INSERT INTO kluby (nameClub) VALUES(@var);
  8. END IF;
  9. END$$
  10. DELIMITER ;


I do tabeli T2 dodawane są nowe wartości.. ale są również dodawane wartości puste ( '' ) które nie mają być dodawane.. (ma po prostu nie robić tego kroku).

Pewnie jest jakiś niewielki błąd.. Średniozaawansowani nie będą pewnie na pierwszy rzut oka zauważą co jest nie tak..
irmidjusz
zamień OR na AND
mikajlo
Dzięki.. ruszyło..

Jednakże mam inny teraz problem i nie chcąć tworzyć nowego tematu podczepie się tutaj i zapytam: czy jest możliwość wykonania takiego triggera, że..
- wstawiam wpis do tabeli zawody z jakąś datą (date)
- w bazie danych są utworzone tabele na wzór - wyniki_rok, tj. wyniki_2010 ; wyniki_2011 ; wyniki_2012...
- i teraz jak dodawana jest data 2013-10-05 do tabeli zawody, to na tej podstawie ma sprawdzić czy istnieje tabela wyniki_2013.. jesli nie to ma ją utworzyć..


Czy jest taki "myk" w ogóle możliwy? Jeśłi tak to proszę o jakieś sugestie (neuralgiczne miejsca z kodem, który należy tu wykorzystać.. czyli jak sprawdzać czy dana tabela isnieje i jak sam rok można wyciągnąć z daty..)
mmmmmmm
Rozwiązanie bezsensowne... Tworzenie tabel dla poszczególnych lat.
Np. policz sumę zakupów jednego klienta za wszystkie lata smile.gif powodzenia.
A tak serio, to w jednej tabeli dodaj sobie indeksowane pole 'rok'. reszta bez zmian.
mikajlo
Wiem, że rozwiązanie jest nie najszczęśliwsze ale tak to wlasnie ma wyglądać... dlatego się pytam czy jest to możliwe do zaimplementowania w triggerze..
irmidjusz
nie pomagamy tworzyć bezsensownych rozwiązań
mikajlo
to nie dziękuje..
alegorn
nie lubie kategoryzowania.
stwierdzenie ze podział tabel na lata jest z punktu złe - nie do końca pokrywa się z prawdą.

potrafię sobie wyobrazić kilka istotnych powodów, dla których takie rozwiązanie ma sens << np generowanie raportów.

czy tutaj jest to dobrym rozwiązaniem? nie wiem. nie znam modelu aplikacji.

jedyna rada - to w procedurze która zakłada tabelę 'zawody_rok', dopisz automatycznie procedurę 'wyniki rok' skoro masz zawody - to musisz miec wyniki, generowanie tego w locie jest bez sensu.

j.
mikajlo
@alegorn - wreszcie jakiś konkretny głos..

Tylko teraz musze znaleźć rozwiązanie do tego.. (składniowe..)
sazian
możesz użyć PREPARE - a przynajmniej tak myślę biggrin.gif

  1. SET @query=concat("SELECT ?,?,",@zmienna3,' FROM tabela WHERE id=?');
  2.  
  3. PREPARE stmt FROM @query;
  4. EXECUTE stmt USING @zmienna1, @zmienna2,@zmienna4;
  5. DEALLOCATE PREPARE stmt;
  6.  


w przykładzie masz pokazane 2 sposoby przekazywania zmiennych, aby zmodyfikować nazwę tabeli chyba będziesz musiał użyć sposobu z concat - zmienna3
mikajlo
No właśnie próbuje coś w tym kierunku i ...

tak jak pisałem muszę wyciągnąć rok z daty zamiast całości.. więc znalazłem coś takiego:

  1. SELECT YEAR(dataZawody) FROM zawodynazwa WHERE dataZawody LIKE '2012%';


i to działa dając tylko rok.. Tylko teraz ten uzyskany rok chciałbym przekazać dalej... i nie wiem jak sad.gif

Chciałbym uzyskać coś takiego:

  1. DELIMITER //
  2. CREATE PROCEDURE dodajZiW(IN Zname varchar(50), IN DATA date)
  3. BEGIN
  4. DECLARE zmienna VARCHAR(1000) DEFAULT str;
  5. SET zmienna = SELECT YEAR(dataZawody) FROM zawodynazwa WHERE dataZawody LIKE '2012%';
  6. (lub coś z CONCAT('SELECT YEAR(dataZawody) FROM zawodynazwa WHERE dataZawody like 'DATA); tylko TO nie chce działać)
  7. I jak mamy wyciągniętą tą date TO możemy zrobić CREATE... (no ale najpierw trzeba przejść pierwszy krok..)
  8. END //
  9. DELIMITER ;
  10.  
  11. [i]gdzie:[/i]
  12. CALL dodajZiW("Zawody","2012-05-04");
  13.  
mmmmmmm
  1. SELECT YEAR(dataZawody) INTO zmienna FROM zawodynazwa WHERE dataZawody LIKE '2012%';

Swoją drogą nie uważasz, że to zapytanie jest trochę bezsensowne? Jaka data zaczyna się na 2012??
mikajlo
Mój błąd.. tam ma być przekazana do procedury zmienna Data

Witam po dłuższej przerwie..
prace z triggerem zostały na moment wstrzymane ale teraz trzeba to dokończyc..

Z racji ograniczeń triggera w związku z tworzeniem nowych tabel zastanawiam się czy jest możliwość takiego rozwiązania..
(są to jeszcze niedopracowane składniową rozwiązania..)

EDIT:
Po prawie dwóch godzinach myślenia nad kodem mam taki komunikat:
"Dynamic SQL is not allowed in stored function or trigger"

Co w przygotowanym poniżej kodzie może wywoływać taki komunikat? I jak sobie z tym poradzić?




Tworzę trigger, który wywołuje w sobie procedure, która otrzymuje jako parametr datę z operacji triggera..
  1. DELIMITER //
  2. CREATE TRIGGER createTableWyniki AFTER INSERT ON zawodynazwa
  3. FOR EACH ROW
  4. BEGIN
  5. #SET @data = (SELECT YEAR(dataZawody) FROM zawodynazwa WHERE dataZawody = NEW.dataZawody);
  6. CALL procCreateTableWyniki(NEW.dataZawody);
  7. END//
  8. DELIMITER ;


a procedura ma za zadanie utworzyć nową tabele, która w nazwie tabeli ma mieć przekazany wcześniej rok, coś na wzór - wyniki_2013
(tylko tutaj chyba trzeba skorzystać z polecenia PREPARE do utworzenia tej zmiennej tablicowej ? Dokładnie nie wiem jak to może/powinno wyglądać..)
  1. DELIMITER //
  2. CREATE PROCEDURE procCreateTableWyniki(IN dataORG CHAR(10))
  3. BEGIN
  4. SET @dataMOD = (SELECT YEAR(dataZawody) FROM zawodynazwa WHERE dataZawody = dataORG); #tutaj z daty '2013-01-01' chce dalej wyciągnąć tylko rok '2013'
  5. SET @wynikiTab = CONCAT('wyniki_',@dataMOD);
  6. SET @sql = CONCAT('CREATE TABLE ',@wynikiTab,' (idWynik int(50) NOT NULL AUTO_INCREMENT)');
  7.  
  8. IF NOT EXISTS (SELECT * FROM lata WHERE rok = @dataMOD) THEN
  9. PREPARE s1 FROM @sql;
  10. EXECUTE s1;
  11. END IF;
  12. END//
  13. DELIMITER ;


Wszelka pomoc/sugestie mile widzane smile.gif
(ps. proszę tylko o nie komentowania tego rozwiązania w stylu - "tak się nie robi, że tabela ma nazwe wyniki_2012, wyniki_2013.." bo ja o tym wiem.. ale to jest jak już wspominałem bardziej udowodnienie tego "że się da".
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.