SQL stored procedures volané z Nette\Database a uzavření kurzoru

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
kedrigern
Člen | 102
+
0
-

Zdravím,

v DB mám strukturu (uzávěrový strom) s kterou pracuji pomocí procedur. To funguje dobře.

Následně jsem se chtěl dotazovat z modelu. Dotazem typu:

$first = $this->con->query("call someproc(1)")->fetchAll();
$second = $this->con->query("call someproc(2)")->fetchAll();

První se provede správně (lze pracovat s daty a tak). Druhý vyhodí chybu:

`PDOException #HY000

SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.`

Zkoušel jsem:

$this->con->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);

$first = $this->con->query("call category_view_subtree(1, 'cs');")->fetchAll();
$second = $this->con->query("call category_view_subtree(2, 'cs');")->fetchAll();

A nezabralo. Když jsem to samé zapsal v PDO, tak to funguje (což mě již zcela mate).

Chybou je, že se neuzavírá kurzor. Nicméně nevím jak ho v Nette\Database uzavřít (a zároveň mít všechny položky).

Samozřejmě umím to vyřešit přes to PDO, ale zajímá mě proč tomu tak je.

EDIT: Přejmenoval jsem vlákno, neb nadpis nereflektoval příspěvek, který jsem při psaní upravoval.

Editoval kedrigern (10. 4. 2013 17:31)

Milo
Nette Core | 1283
+
0
-

Nette\Database pro fetchAll() používá vlastní metodiku a ne PDOStatement::fetchAll(). Zkus to takhle:

$stmt = $this->con->query("call someproc(1)");
$first = $stmt->fetchAll();
$stmt->getPdoStatement()->closeCursor();

$stmt = $this->con->query("call someproc(2)");
$second = $stmt->fetchAll();
$stmt->getPdoStatement()->closeCursor();

Editoval Milo (11. 4. 2013 11:32)

kedrigern
Člen | 102
+
0
-

Moc děkuji, pomohlo. Dokonce je to o jeden příkaz jednodušší:

$stmt = $this->con->query("call someproc(1)");
$first = $stmt->fetchAll();
$stmt->closeCursor();

$stmt = $this->con->query("call someproc(2)");
$second = $stmt->fetchAll();
$stmt->closeCursor();
hrach
Člen | 1838
+
+1
-

No, to druhe bych rozhodne nedelal, zanasis si do aplikace nekolik druhu rozhrani zbytecne. ten bug fixneme.

Milo
Nette Core | 1283
+
+1
-

Pro doplnění…

# Nette 2.0.x
$stmt = $connection->query() // vrací PDOStatement, volá se rovnou
$stmt->closeCursor()

# Nette 2.1 (současný dev)
$stmt = $connection->query() // vrací Nette\Database\Statement, volá se přes
$stmt->getPdoStatement()->closeCursor();