Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Wyzwalacz - tworzenie unikalnego identyfikatora
Mephis
post 15.10.2015, 21:50:39
Post #1





Grupa: Zarejestrowani
Postów: 94
Pomógł: 1
Dołączył: 16.12.2012

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


Witam.

Chciałbym stworzyć wyzwalacz, który byłby aktywowany przed poleceniem INSET do tabeli, a jego celem byłoby stworzenie unikalnego identyfikatora.
Wyzwalacz miałby za zadanie wylosowanie liczby z zakresu od 10000 do 65535 i sprawdzenie, czy w tabeli istnieje już taki identyfikator. Następnie wylosowany ciąg liczb zapisał jako nowy identyfikator. Wiem, że mógłbym użyć tutaj autoinkrementacji, ale nie chcę, by po identyfikatorze można było stwierdzić ilość rekordów w tabeli i chciałbym, żeby każdy identyfikator miał taką samą ilość cyfr.

Poniżej mam tylko zarys tego, jak wydaje mi się, że mogłoby to wyglądać. Problem pojawia się niestety tuż przy deklaracji zmiennej, albowiem jakakolwiek próba przypisania wartości do niej wartości kończy się niezbyt jasnym dla mnie błędem w rodzaju "#1064 - check the manual that corresponds to your MySQL server version for the right syntax to user near '' at line 4" a jeżeli już mi się uda, to ten sam błąd będzie dotyczyć tego, co znajdzie się pod deklaracją zmiennych.
  1. DROP TRIGGER IF EXISTS `wyzwalacz`;
  2. CREATE DEFINER=`root`@`localhost` TRIGGER `wyzwalacz` BEFORE INSERT ON `tabela` FOR EACH ROW
  3. BEGIN
  4.  
  5. SET @rand = ROUND((RAND() * 55534 + 10000), 0);
  6.  
  7. WHILE ((SELECT `id` FROM `tabela` WHERE `id` = @rand) == @rand) DO
  8. SET @rand = ROUND((RAND() * 55534 + 10000), 0);
  9. END;
  10.  
  11. SET new.id = @rand;
  12.  
  13. END;

Rozumiem, że gdzieś tutaj tkwi podstawowy błąd, ale ja już sam nie wiem gdzie on jest, skoro błędy tego rodzaju wyskakują mi nawet po kopiowaniu przykładów z manuala.
Go to the top of the page
+Quote Post
kartin
post 15.10.2015, 22:59:35
Post #2





Grupa: Zarejestrowani
Postów: 246
Pomógł: 79
Dołączył: 25.05.2010

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


Cytat(Mephis @ 15.10.2015, 22:50:39 ) *
"#1064 - check the manual that corresponds to your MySQL server version for the right syntax to user near '' at line 4" a jeżeli już mi się uda, to ten sam błąd będzie dotyczyć tego, co znajdzie się pod deklaracją zmiennych.
  1. DROP TRIGGER IF EXISTS `wyzwalacz`;
  2. CREATE DEFINER=`root`@`localhost` TRIGGER `wyzwalacz` BEFORE INSERT ON `tabela` FOR EACH ROW
  3. BEGIN
  4.  
  5. SET @rand = ROUND((RAND() * 55534 + 10000), 0);
  6.  
  7. WHILE ((SELECT `id` FROM `tabela` WHERE `id` = @rand) == @rand) DO
  8. SET @rand = ROUND((RAND() * 55534 + 10000), 0);
  9. END;
  10.  
  11. SET new.id = @rand;
  12.  
  13. END;

Rozumiem, że gdzieś tutaj tkwi podstawowy błąd, ale ja już sam nie wiem gdzie on jest, skoro błędy tego rodzaju wyskakują mi nawet po kopiowaniu przykładów z manuala.


Słabo czytałeś manuala ;P
Jeśli wykonujesz zapytania w takiej formie jak to przedstawiane, to rzeczywiście jest podstawowy błąd składni. Średnik standardowo jest traktowany jako koniec zapytania. Zatem tutaj jest 6 zapytań zamiast 2.

Trzeba zmienić znak końca zapytania
  1. DELIMITER //
  2.  
  3. DROP TRIGGER IF EXISTS `wyzwalacz`//
  4.  
  5. CREATE TRIGGER `wyzwalacz` BEFORE INSERT ON `tabela` FOR EACH ROW
  6. BEGIN
  7. ...
  8. END //
  9.  
  10. DELIMITER ;


--------------------
Jeśli ten post pomógł to kliknij przycisk po lewej stronie.
Nie pomagam przez PW, GG, e-mail, faks, telegram, znaki dymne, ...
Go to the top of the page
+Quote Post
Mephis
post 16.10.2015, 00:15:53
Post #3





Grupa: Zarejestrowani
Postów: 94
Pomógł: 1
Dołączył: 16.12.2012

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


Czyli chodzi o ten DELIMITER. O dziwo kod który napisałem działa jak należy...

Dla testów obniżyłem zakres do paru wolnych miejsc. Gdy się one wszystkie zapełniły, nastąpiła nieskończona pętla. Pytanie mam następujące: w jaki sposób przerwać wtedy cały skrypt, łącznie z zapytaniem INSET dla którego wykonywany jest wyzwalacz? No i jak optymalnie sprawdzić, czy te miejsca są już zapełnione (zliczanie rekordów w bazie przy każdej pętli to chyba kiepski pomysł)?

A tak przy okazji; istnieje jakaś funkcja, która zwróciłaby mi długość/rozmiar pola, albo jeżeli to int to żeby zwróciła maksymalną liczbę, którą pole może przyjąć?

Ten post edytował Mephis 16.10.2015, 02:07:02
Go to the top of the page
+Quote Post

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 Wersja Lo-Fi Aktualny czas: 12.06.2024 - 19:54