Oznámení
Opakované volání procedur
před 10 lety
- MartinJanda
- Člen | 63
Dobrý den,
volám ve smyčce uloženou proceduru. První průchod v pořádku, druhý
vyvolá:
DibiDriverException #2014
Commands out of sync; you can't run this command now
Proceduru volám klasicky:
dibi::query(„call jmeno_procedury()“);
V čem je přesně problém? Jak to vyřešit nebo obejít?
Díky za každou radu.
před 10 lety
- MartinJanda
- Člen | 63
Ještě doplním, že jde o database.driver = mysqli
před 10 lety
- MartinJanda
- Člen | 63
Zatím jsem to provizorně prasácky vyřešil dibi::disconnect() a znovu connect, ale správné řešení by mě zajímalo, protože v projektu, který dělám bude volání procedur časté v rámci jednoho připojení…
před 10 lety
- LM
- Člen | 206
Zkus to volat takhle:
dibi::query("call jmeno_procedury()")->free();
a koukni na http://dev.mysql.com/…of-sync.html.
před 10 lety
- MartinJanda
- Člen | 63
Díky za radu. Podívám se na to.
před 10 lety
- MartinJanda
- Člen | 63
Ten zápis dibi::query("call jmeno_procedury()")->free();
problém řeší u procedur, které nevracejí výsledky.
Jak to správně zapsat, když procedura vrací data? Zkoušel jsem:
$query = dibi::nativeQuery("call jmeno_procedury()");
$data = $query->fetchAll();
$query->free();
Ale při druhém průchodu se znovu objeví
DibiDriverException #2014 Commands out of sync; you can't run this command now
.
Jak v takovém případě zdroje správně uvolnit z paměti?
před 10 lety
- MartinJanda
- Člen | 63
Zkoušel jsem využít pdo driver, ale ten nemá implementováno docela dost věcí :-(
Asi budu muset použít samotné PDO.
Každopádně díky LM za pomoc.
před 10 lety
- Jod
- Člen | 703
Mne tam chýbalo cachovanie query resultov.
před 10 lety
- MartinJanda
- Člen | 63
No já bych nejraději zůstal u dibi s mysqli driverem, ale to opakované volání procedur (vracejících data) prostě potřebuju a nevím kde je problém/jak to vyřešit :(
před 10 lety
- LM
- Člen | 206
Ještě jeden odkaz: http://forums.mysql.com/read.php?… , podle všeho
CALL
v mysql vrací vždy jeden výsledek navíc, info. Což je
nešťastné, chce to feature request.
před 10 lety
- Ondřej Bouda
- Člen | 2
Pro podporu získávání výsledků z volání procedur jsem si napsal rozšíření mysqli driveru, které první výsledek uloží a ostatní zahodí. Funguje docela dobře a i kód by byl docela krátký:
<?php
/**
* MySqli driver with support for MySQL stored procedures producing result sets.
*
* Fetches only the first result set, throws away the others.
*
* @uses DibiMySqliDriver
*/
class DibiMySqliProcedureDriver extends DibiMySqliDriver {
/**
* Executes the SQL query.
* If the query is a procedure call, uses mysqli_multi_query and throws away everything after
* the first result set.
* @param string SQL statement
* @return DibiDriver|NULL
* @throws DibiDriverException
*/
public function query($sql)
{
if (!preg_match('#\s*CALL\s(.+)#i', $sql)) {
return parent::query($sql);
}
@mysqli_multi_query($this->connection, $sql); // intentionally @
if (mysqli_errno($this->connection)) {
$this->trashMoreResults();
throw new DibiDriverException(mysqli_error($this->connection), mysqli_errno($this->connection), $sql);
}
$this->resultSet = mysqli_store_result($this->connection);
$this->trashMoreResults();
return is_object($this->resultSet) ? clone $this : NULL;
}
/**
* Throws away all the remaining results from the most recent query.
*/
private function trashMoreResults()
{
if (mysqli_more_results($this->connection)) {
while (mysqli_next_result($this->connection));
}
}
}
?>
jen kdyby v driveru DibiMySqliDriver atributy connection a resultSet nebyly private :(