Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Zły kod błędu w SQLException na bazie MySQL
Forum PHP.pl > Forum > PHP > Object-oriented programming
mike
Mam problem z pogranicza php i MySQL ale zdecydowałem się umieścić temat tutaj.

Zaczne od kodu:

AddQuestionAction.class.php
  1. <?php
  2.  
  3. // ...
  4.  
  5. public function execute()
  6. {
  7.  
  8. // Pobranie obiektów z kontekstu
  9. $objController = $this->getContext()->getController();
  10. $objRequest = $this->getContext()->getRequest();
  11. // ---
  12.  
  13. // Pobranie modeli
  14. $objModel = $objController->getModel( 'FAQ', 'AddQuestion' );
  15. // ---
  16.  
  17. try
  18. {
  19.  
  20. $objModel->addQuestion();
  21.  
  22. }
  23. catch( SQLException $objException )
  24. {
  25.  
  26. // Jakieś tam operacje
  27.  
  28.  
  29. return View::ERROR;
  30.  
  31. }
  32.  
  33. return View::SUCCESS;
  34.  
  35. }
  36.  
  37. // ...
  38.  
  39. ?>


AddQuestionModel.class.php
  1. <?php
  2.  
  3. // ...
  4.  
  5. public function addQuestion()
  6. {
  7.  
  8. // Pobranie modeli
  9. $objModel = $this->objController->getGlobalModel( 'FAQ' );
  10. // ---
  11.  
  12. // Pobranie parametrów żądania
  13. $strSectionName = $this->objRequest->getParameter( 'name' );
  14. $intLanguageId = $this->objRequest->getParameter( 'languageId' );
  15. $strQuestion = $this->objRequest->getParameter( 'question' );
  16. $strAnswer = $this->objRequest->getParameter( 'answer' );
  17. // ---
  18.  
  19. // Pobranie danych z modeli
  20. $intMaxCurrentPosition = $objModel->getLastPosition( $intLanguageId );
  21. // ---
  22.  
  23. $objStatment = $this->objConnection->prepareStatement( 'INSERT INTO faq SET languageId = ?, position = ?, question = ?, answer = ?' );
  24.  
  25. $arrParams = array(
  26.  $intLanguageId,
  27.  ( $intMaxCurrentPosition + 1 ),
  28.  $strQuestion,
  29.  $strAnswer
  30. );
  31. $intAffectedRows = $objStatment->executeUpdate( $arrParams );
  32.  
  33. if( $intAffectedRows > 0 )
  34. {
  35.  
  36. return true;
  37.  
  38. }
  39.  
  40. return false;
  41.  
  42. }
  43.  
  44. // ....
  45.  
  46. ?>


Jak widać powyżej - banalna operacja. W Akcji pobieram model i wykonuje jego metodę. Szafa gra, a przynajmniej powinna sad.gif

Podam dodatkowo strukturę tabeli faq:
  1. CREATE TABLE `faq` (
  2. `id` int(10) NOT NULL AUTO_INCREMENT,
  3. `languageId` int(2) NOT NULL DEFAULT '0',
  4. `position` int(10) NOT NULL DEFAULT '1',
  5. `question` varchar(255) NOT NULL DEFAULT '',
  6. `answer` text NOT NULL,
  7. PRIMARY KEY (`id`),
  8. UNIQUE KEY `question` (`languageId`,`question`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


I teraz problem. Na pola languageId + question jest założony klucz unikalny. Co powinno zaowocowac wyrzuconym wyjątkiem podczas próby dodania tych samych danych.
I owszem wyjątek leci, ale ...
... z kodem błędu 0 exclamation.gif!
A przecież zaburzenie unikalności klucza to kod błędu 1062 (jak się nie mylę).

Dlaczego tak się dzieje :?:

Dodatek:
MySQL 4.1.7
php 5.0.4
Abstrakt bazodanowy to Creole 1.0.9
Framework Mojavi 3.0.0 dev ( + moje zmiany ).
nospor
Linia 32: robisz sql'owy insert a wywolujesz metode update. To chyba coś nie tak jest smile.gif. sprawdź i daj znać

edit po poście M4chu:
no faktycznie, przeczytalem manuala i widzę że się myliłem. Ale plama na honorze sadsmiley02.gif Mój błąd
M4chu
Cytat(nospor @ 2005-09-27 08:52:31)
Linia 32: robisz sql'owy insert a wywolujesz metode update. To chyba coś nie tak jest smile.gif. sprawdź i daj znać

Wszystko w porządku: w Creole do inserta i update'a i delete'a używamy executeUpdate - RTFM winksmiley.jpg
A co do błędu, to może właśnie znalazleś buga, bo wyglada na dobrze napisane.
mike
Znalazłem ...
... niestety.

Mówię niestety bo natura błędu bardzo mnie zmartwiła. Jest to duże niedociągnięcie twórców Creole'a.

Zerknijcie jak w klasie SQLException wywoływany jest konstruktor klasy nadrzędnej (klasy Exception):
SQLException.php
  1. <?php
  2.  
  3. // ...
  4.  
  5. /**
  6.  * Constructs a SQLException.
  7.  * @param string $msg Error message
  8.  * @param string $native Native DB error message.
  9.  * @param string $userinfo More info, e.g. the SQL statement or the connection s
    tring that caused the error.
  10.  */
  11. public function __construct($msg, $native = null, $userinfo = null)
  12. {
  13. parent::__construct($msg);
  14. if ($native !== null) {
  15. $this->setNativeError($native);
  16. }
  17. if ($userinfo !== null) {
  18. $this->setUserInfo($userinfo);
  19. }
  20. }
  21.  
  22. // ...
  23.  
  24. ?>

... no właśnie sad.gif Bez drugiego parametru, który to jest kodem błędu.

Jak tak można? I to jeszcze pisząc pod php5 :?:

Bardzo nieładnie, bardzo.

Będę musiał przepisać Creole'a, albo poszukać altenatywy. A wielka szkoda, bo poza brakiem debugera myślałem że nie ma wad.
Vengeance
A czy czasem to
  1. <?php
  2.  
  3. if ($native !== null) {
  4. $this->setNativeError($native);
  5. }
  6.  
  7. ?>

nie odpowiada za późniejsze ustawienie ów błędu? Może autorzy przewidzieli pobieranie kodu błędu z innego argumentu/inną metodą ?
mike
Niestety.

Też się łudziłem, ale przejrzałem kod Creole'a pod tym kątem i to jest fakt. Smutny zresztą.

W SQLException z Creole'a nie ma kodów błędów.

(Ale nic nie szkodzi, uzupełniłem sobie Creole'a o to)
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.