Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL]Dodawanie rekordu jeżeli nie istnieje
Dukov
post 4.11.2018, 13:51:54
Post #1





Grupa: Zarejestrowani
Postów: 69
Pomógł: 0
Dołączył: 21.03.2017

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


Tak jak w temacie, chcę dodać do bazy rekord, jeżeli ten nie istnieje, a jeżeli istnieje zwrócić false, próbowałem już setki rozwiązań z stackoverflow i za każdym razem wywala błąd
  1. SELECT CASE WHEN EXISTS (
  2. SELECT *
  3. FROM users
  4. WHERE login = :login
  5. OR
  6. mail = :mail
  7. )
  8. THEN
  9. INSERT INTO users (login,mail,name,city,avatar,ip_addr,reg_date,last_log_date,active,permissions,famous,rang,banned,warns) VALUES (:login,:mail,:password,0,0,"$ip","$date",0,0,0,0,0,0,0, ))
  10. ELSE
  11. CAST(0 AS BIT) END

albo to:
  1. INSERT INTO users (login,mail,password,name,city,avatar,ip_addr,reg_date,last_log_date,active,permissions,famous,rang,banned,warns) VALUES (:login,:mail,:password,0,0,0,"$ip","$date",0,0,0,0,0,0,0 )
  2. SELECT DISTINCT login
  3. FROM users
  4. WHERE
  5. NOT EXISTS (SELECT 1 FROM users
  6. WHERE login = :login)
  7.  
  8.  
  9.  
  10.  
  11.  


Ten post edytował Dukov 4.11.2018, 13:52:42
Go to the top of the page
+Quote Post
viking
post 4.11.2018, 13:59:55
Post #2





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Złap wyjątek dla insert i zamień sobie wtedy odpowiedź na false.


--------------------
Go to the top of the page
+Quote Post
Dukov
post 4.11.2018, 14:03:01
Post #3





Grupa: Zarejestrowani
Postów: 69
Pomógł: 0
Dołączył: 21.03.2017

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


A możesz nieco jaśniej? Bazy danych to zdecydowanie nie jest moja mocna strona, zresztą dlatego teraz pisze, żeby podszlifować umiejętności.
Go to the top of the page
+Quote Post
viking
post 4.11.2018, 14:34:48
Post #4





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


  1. try {
  2. zapytanie insert które w przypadku zduplikowania danych (maila lub loginu) zwróci wyjątek
  3. } catch (\PDOException $e) {
  4. return false;
  5. }


--------------------
Go to the top of the page
+Quote Post
Dukov
post 4.11.2018, 14:53:54
Post #5





Grupa: Zarejestrowani
Postów: 69
Pomógł: 0
Dołączył: 21.03.2017

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


No dobrze, rozumiem o co chodzi, tylko jak mam zwrócić ten wyjątek. zresztą wolałbym zrobić to w jednym zapytaniu, bo mam obiekt z metodami odnoszącymi się do bazy danych, a w tych metodach chcę tylko dołaczać zapytanie jako file_get_contents, żeby nie było pomieszanych zapytań z PHP, bo będzie to nieczytelne.
Konkretnie mam wysyłany json przez ajax do pliku controller.php, w nim switcha i dołączanie odpowiednicyh plików, jeżeli dane przejdą przez walidacje, to tworzy obiekt wspomnianej bazy danych, a zapytania są w folderze queries.
Go to the top of the page
+Quote Post
viking
post 4.11.2018, 15:12:20
Post #6





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Sposób dołączania zapytania nie ma żadnego znaczenia. Błędne zapytanie spowodfuje automatyczne rzucenie wyjątku - dla PDO $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


--------------------
Go to the top of the page
+Quote Post
vokiel
post 4.11.2018, 16:15:45
Post #7





Grupa: Zarejestrowani
Postów: 2 592
Pomógł: 445
Dołączył: 12.03.2007

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


Nie wystarczy
Kod
INSERT IGNORE ...
?

A jeśli już z łapaniem Exception, to trzeba sprawdzić jaki to jest wyjątek - żeby w ten sam sposób nie obsługiwać wszystkich.


--------------------
Go to the top of the page
+Quote Post
viking
post 4.11.2018, 16:19:29
Post #8





Grupa: Zarejestrowani
Postów: 6 365
Pomógł: 1114
Dołączył: 30.08.2006

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


Czyli według Ciebie lepsze będzie zignorowanie? To wygląda na rejestrację. Nie ma znaczenia jaki błąd sypnie baza. Ważny jest efekt końcowy czyli brak rekordu.


--------------------
Go to the top of the page
+Quote Post
mmmmmmm
post 5.11.2018, 08:45:00
Post #9





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

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


Wytłumaczę ci najprościej jak się da. Baza danych porównuje zbiory. Zbiór twoich danych wejściowych (daną wejściową jest rekord) ze zbiorem danych z tabeli.
Utwórz sobie taki zbiór i go go porównaj z tabelą. Jesli go nie znajdzie, to wtedy dodaj.
Czyli po kolei
Utworzenie zbioru jednoelementowego:
  1. SELECT :login AS login, :mail AS mail, :password AS pass, :ip AS ip, :DATA AS date

Teraz sprawdzasz, czy danych zbiór istnieje. Warunkiem istnienia jest klucz, czyli w tym przypadku login. Jak najłatwiej sprawdzić? Połączyć lewostronnie po kluczu i sprawdzić, czy w drugiej tabeli znalazł dany rekord.
  1. SELECT * FROM
  2. (SELECT :login AS login, :mail AS mail, :password AS pass, :ip AS ip, :DATA AS date) AS sub
  3. LEFT JOIN
  4. users AS u
  5. ON u.login=sub.login
  6. WHERE
  7. u.login IS NULL

Jeśli zapytanie zwróci ci jakikolwiek rekord (a może zwrócić tylko jeden), to wtedy dodajesz go do `users`. Zapytanie jest o tyle bezpieczne, że możesz je wykonywać ile razy chcesz - rekord doda się tylko raz (bo za każdą następną próbą już będzie)
  1. INSERT INTO users(login, mail, pass, ip, date)
  2. SELECT sub.* FROM
  3. (SELECT :login AS login, :mail AS mail, :password AS pass, :ip AS ip, :DATA AS date) AS sub
  4. LEFT JOIN
  5. users AS u
  6. ON u.login=sub.login
  7. WHERE
  8. u.login IS NULL
Go to the top of the page
+Quote Post
Pyton_000
post 5.11.2018, 10:44:13
Post #10





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

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


Ło matko.. najlepiej jak by napisać do tego jeszcze jakiś mikroserwis który będzie to sprawdzał...


Do Autora tematu. Załóż 2 indeksy Unique w Bazie na pola `email` i `username` i wykonuj normalny INSERT bez żadnych pierdoł.

W przypadku próbu wrzucenia rekordu nie unikalnego po prostu się nie stworzy a PDO wyrzuci Exceprion który musisz złapać.

Tu masz przykład:
Kod
try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "DataBase Error: The user could not be added.<br>".$e->getMessage();
} catch (Exception $e) {
  echo "General Error: The user could not be added.<br>".$e->getMessage();
}
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: 28.03.2024 - 13:59