Oznámení
Fatal Error: Wrong parameters for Exception([string $exception … při chybném SQL (Dibi)
před 8 lety
- mr.mac
- Člen | 87
Při nesprávně vygenerovaném SQL příkazu se objevuje v laděnce chyba (zvýrazněný řádek 43):
Fatal Error
Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]]) search►
Source file ▼
File: C:\xamlite\htdocs\_Libs\Dibi\libs\DibiException.php Line: 43
36: * Construct a dibi exception.
37: * @param string Message describing the exception
38: * @param int Some code
39: * @param string SQL command
40: */
41: public function __construct($message = NULL, $code = 0, $sql = NULL)
42: {
43: parent::__construct($message, (int) $code);
44: $this->sql = $sql;
45: // TODO: add $profiler->exception($this);
46: }
47:
48:
49:
50:
Myslím si, že to je nedostatečně ošetřená výjímka při nesprávném
SQL, která se objevuje vždy při chybném dotazu. Používám Dibi 1.5rc.
Bohužel v chybné SQL není vidět při použití fireBug profileru.
před 8 lety
- Milo
- Nette Core | 1119
Uprav si řádek 43 na
parent::__construct($message, (int) $code, NULL);
a zkus.
Edit: Ikdyž je to asi blbost.
Editoval Milo (20. 10. 2011 14:29)
před 8 lety
- mr.mac
- Člen | 87
Milo napsal(a):
Uprav si řádek 43 na
Měl jsi pravdu, nepomohlo to.
Any idea?
před 8 lety
- Milo
- Nette Core | 1119
A na jaké databázi a verze PHP? Dej sem kus kódu s tím špatným SQL dotazem…
před 8 lety
- mr.mac
- Člen | 87
Milo napsal(a):
A na jaké databázi a verze PHP?
Používám MS SQL 2008R2 Express a PHP 5.3. Původní driver mssql.php
v dibi mi nechodil, neboť funkce driveru mssql jako např. mssql_query() a
podbné nejsou asi už podporovány pro tuto veri SQL DB. Upravil jsem si tedy
mssql.php dibi driver na sqlsrv.php driver, který podporuje sqlrv_xxx() funkce
PHP 5.3. Vcelku mi vše šlape až asi na nějaké drobnosti (např. teď
ladím metodu applyLimit – parametr offset (s vnořeným SELECTem a funkcí
ROW_NUMBER()). Asi všechno ale není úplně ok, neboť jakákoli chyba
v nette nakonec skočí do chyby exception a debugger mi vypíše mi SQL
přílak a za ním chybovou hlášku (výše zníněnou), pokud chyba v běhu
programu nenastane, nic se neprojeví.
Příklad takové chyby detailněji vypsané debuggerem:
EXPLAIN SELECT * FROM ( SELECT f.*, d.zkratka [dzkratka], a.ulice [a_ulice], a.cp [a_cp], o.id [a_id_obce],
o.nazev [m_obec], o.psc [m_psc], k.nazev [m_kraj], k.zkratka [m_zkraj], s.nazev [m_stat], s.zkratka [m_zstat],
a.id_kraje [a_id_kraje], a.id_staty [a_id_staty] FROM firmy f LEFT JOIN druhy_firem d ON f.id_druhy_firem=d.id
LEFT JOIN adresy a ON f.id_adresy=a.id
LEFT JOIN obce o ON a.id_obce=o.id
LEFT JOIN kraje k ON a.id_kraje=k.id
LEFT JOIN staty s ON a.id_staty=s.id WHERE f.id=1) t
Fatal error: Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]]) in C:\xamlite\htdocs\_Libs\Dibi\libs\DibiException.php on line 45 Call Stack: 0.0012 343432
1. {main}() C:\xamlite\htdocs\nx\www\index.php:0 0.0027 365752
2. require('C:\xamlite\htdocs\nx\app\bootstrap.php') C:\xamlite\htdocs\nx\www\index.php:20 0.0547 6214064
3. Nette\Application\Application->run() C:\xamlite\htdocs\nx\app\bootstrap.php:51 0.0648 7017816
4. Nette\Application\UI\Presenter->run() C:\xamlite\htdocs\_Libs\Nette\Application\Application.php:135 0.0894 8094416
5. Nette\Application\UI\PresenterComponent->tryCall() C:\xamlite\htdocs\_Libs\Nette\Application\UI\Presenter.php:185 0.0897 8095512
6. Nette\Reflection\Method->invokeNamedArgs() C:\xamlite\htdocs\_Libs\Nette\Application\UI\PresenterComponent.php:98 0.0897 8095744
7. ReflectionMethod->invokeArgs() C:\xamlite\htdocs\_Libs\Nette\Reflection\Method.php:57 0.0897 8095760
8. FirmaPresenter->renderDetail() C:\xamlite\htdocs\_Libs\Nette\Reflection\Method.php:57 0.0940 8141720
9. Nette\Diagnostics\Debugger::_errorHandler() C:\xamlite\htdocs\_Libs\Nette\Reflection\Method.php:85 0.0940 8150896
10. Nette\Diagnostics\Debugger::_exceptionHandler() C:\xamlite\htdocs\_Libs\Nette\Diagnostics\Debugger.php:471 0.3915 8265768
11. Nette\Diagnostics\Bar->render() C:\xamlite\htdocs\_Libs\Nette\Diagnostics\Debugger.php:415 0.3927 8271472
12. DibiProfiler->getPanel() C:\xamlite\htdocs\_Libs\Nette\Diagnostics\Bar.php:62 0.3927 8272296
...
Ještě se v tom tak moc neorientuji, abych z toho něco vyčetl. O konkrétní SQl příkaz asi nejde.
Editoval mr.mac (22. 11. 2011 17:44)
před 8 lety
- Milo
- Nette Core | 1119
Pastni sem řádek z DibiSqlSrvDriver->query()
tam kde je
throw
± 10 řádků okolo. Resp. zkus upravit:
// DibiExeption:43
parent::__construct($message, (int) $code);
// na
parent::__construct((string) $message, (int) $code);
před 8 lety
- mr.mac
- Člen | 87
Milo napsal(a):
zkus upravit:// DibiExeption:43 parent::__construct($message, (int) $code); // na parent::__construct((string) $message, (int) $code);
Díky moc Milo za radu – POMOHLO TO – přetypování $message na (string) je to správné řešení, teď mi laděnka krásně vypíše SQL příkaz a hnedle snáz mohu najít chybu. Doporučuji implementovat.
před 8 lety
- Milo
- Nette Core | 1119
Fajn že jsme k tomu doiterovali. Ona v ostatních drivers chyba není.
Tipnul bych si, že do throw new DibiDriverException
ve svém
driveru předáváš sqlsrv_errors()
což vrací pole nebo NULL a
ne string ;)
před 8 lety
- mr.mac
- Člen | 87
Je to přesně tak, moje metoda query vypadá následovně:
public function query($sql){
$res = @sqlsrv_query($this->connection, $sql);
if ($res === FALSE) {
throw new DibiDriverException(sqlsrv_errors(), 0, $sql);
} elseif (is_resource($res)) {
return $this->createResultDriver($res);
}
}
A jak se píše v dokmentaci krom errors sqlsrv_errors()
vrací
při bezchybném provedení SQL NULL.
Editoval mr.mac (9. 11. 2011 21:05)
před 8 lety
- mr.mac
- Člen | 87
Ještě jsem sqlsrv.php
driver dovylepšil, aby mi laděnka
vypisovala úplné info o chybě (psalo to jen slovo
Array
):
public function query($sql)
{
$res = @sqlsrv_query($this->connection, $sql);
if ($res === FALSE) {
if( ($errors = sqlsrv_errors() ) != null) {
$msg = '';
foreach( $errors as $error ) {
$msg .= "SQLSTATE: ".$error[ 'SQLSTATE'].' >> ';
$msg .= "code: ".$error[ 'code']." >> ";
$msg .= "message: ".$error[ 'message']." << ";
}
}
throw new DibiDriverException($msg, 0, $sql);
} elseif (is_resource($res)) {
return $this->createResultDriver($res);
}
}