Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [MySQL]Dodawanie rekordu jeżeli nie istnieje
Dukov
post
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
 
Start new topic
Odpowiedzi (1 - 9)
viking
post
Post #2





Grupa: Zarejestrowani
Postów: 6 381
Pomógł: 1116
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
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
Post #4





Grupa: Zarejestrowani
Postów: 6 381
Pomógł: 1116
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
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
Post #6





Grupa: Zarejestrowani
Postów: 6 381
Pomógł: 1116
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
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
Post #8





Grupa: Zarejestrowani
Postów: 6 381
Pomógł: 1116
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
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
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
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 24.12.2025 - 21:14