[PHP&PDO&MYSQL] Problem z zapytaniem

0

Witam.
Mam serwer WAMP i klasę ( na dole postu ), gdzie $this->Date['XVweb']->DataBase to klasa PDO.
Na początek wysyłam zapytanie

DELETE FROM `online` WHERE `ip` = :IPExec OR (czas z php) - `time` > 60 ;
 INSERT INTO `online` ( `ip` , `location` , `time` , `browser` , `userloged` ) VALUES ( :IPExec , :UrlExec, 1243769540, :BrowserExec, :UserLoged );

Tutaj wszystko jest ok. Pięknie usuwa i dodaje.
A następnie jak je wykonam to chcę dać zapytanie:

SELECT count(*) AS `OnlineCount`, (SELECT count(*) FROM `online` WHERE `Userloged` IS NOT NULL) AS `UserLoged` FROM `online`

No i tutaj zaczynają się schodki. Otrzymuje komunikat o błędzie:
PDOException: 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. in E:\wamp\www\Xvweb\core\libraries\Online.XVWeb.class.php on line 86

No i czego ja chcę?
1.Jak połączyć te 2 zapytania razem, by wynikiem był wynik zapytania SELECT?
lub
2. Jak ominąć ten błąd? Proszę nie pisać że mam włączyć buforowanie zapytań, bo już wyłączałem, włączałem i nic.

<?php

/************************************************************************************************/
class OnlineClass
/************************************************************************************************/
{	var $Date;
	/************************************************************************************************/
	public function __construct(&$Xvweb, $UrlLocation=null) {
		$this->Date['XVweb'] = &$Xvweb;
		$this->Date['Time'] = 60;
		if(!isset($this->Date['XVweb']->Date['DataBaseOnline'])){
			$this->Date['XVweb']->Date['DataBaseOnline'] = array(
			"DataBaseOnline" => "online",
			"IP" => "ip",
			"UrlLocation" => "location",
			"DateTime" => "time",
			"UserLoged" => "userloged",
			"Browser" => "browser"
			);
		}
		
		
		if(!is_null($UrlLocation) && (eregi($_SERVER['HTTP_HOST'], substr($UrlLocation, 0, strlen($_SERVER['HTTP_HOST'])+12)))){ // zminiejsz link
			$this->Date['UrlLocation'] = $UrlLocation;
		}
		
		$this->OnlineInit();
		
	}
	/************************************************************************************************/
	public function OnlineInit(){
	try {
		$Online = $this->Date['XVweb']->DataBase->prepare('
	DELETE FROM 
		`'.($this->Date['XVweb']->DataBasePrefix).($this->Date['XVweb']->Date['DataBaseOnline']['DataBaseOnline']).'` 
		WHERE 
		`'.($this->Date['XVweb']->Date['DataBaseOnline']['IP']).'` = :IPExec 
		OR
		
		'.time().' - `'.($this->Date['XVweb']->Date['DataBaseOnline']['DateTime']).'` > '.$this->Date['Time'].' ;
		
				INSERT INTO `'.($this->Date['XVweb']->DataBasePrefix).($this->Date['XVweb']->Date['DataBaseOnline']['DataBaseOnline']).'`  (
`'.($this->Date['XVweb']->Date['DataBaseOnline']['IP']).'` ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['UrlLocation']).'` ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['DateTime']).'` ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['Browser']).'`  ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['UserLoged']).'` 
)
VALUES (
:IPExec , :UrlExec, '.time().', :BrowserExec, :UserLoged
);
');
echo '
	DELETE FROM 
		`'.($this->Date['XVweb']->DataBasePrefix).($this->Date['XVweb']->Date['DataBaseOnline']['DataBaseOnline']).'` 
		WHERE 
		`'.($this->Date['XVweb']->Date['DataBaseOnline']['IP']).'` = :IPExec 
		OR
		
		'.time().' - `'.($this->Date['XVweb']->Date['DataBaseOnline']['DateTime']).'` > '.$this->Date['Time'].' ;
		
				INSERT INTO `'.($this->Date['XVweb']->DataBasePrefix).($this->Date['XVweb']->Date['DataBaseOnline']['DataBaseOnline']).'`  (
`'.($this->Date['XVweb']->Date['DataBaseOnline']['IP']).'` ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['UrlLocation']).'` ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['DateTime']).'` ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['Browser']).'`  ,
`'.($this->Date['XVweb']->Date['DataBaseOnline']['UserLoged']).'` 
)
VALUES (
:IPExec , :UrlExec, '.time().', :BrowserExec, :UserLoged
);
';
		$Online->execute(array(
		":IPExec" => $_SERVER['REMOTE_ADDR'],
		":UrlExec" => $this->Date['UrlLocation'],
		":BrowserExec" => $_SERVER['HTTP_USER_AGENT'],
		":UserLoged" => $this->Date['XVweb']->Session->Session('Logged_User')
		));
 unset($Online);  
 } catch (PDOException $e) {
			$this->Date['XVweb']->ErrorClass($e);
		}
	}
	/************************************************************************************************/
	public function GetLogedCount(){
		$OnlineCount = $this->Date['XVweb']->DataBase->query("SELECT count(*) AS `OnlineCount`, (SELECT count(*) FROM `online` WHERE `Userloged` IS NOT NULL) AS `UserLoged` FROM `online`");
		//$OnlineCount->execute();
		print_r($OnlineCount->fetchAll());
	}
	/************************************************************************************************/
}

?>
0

Właśnie bawię się MySQL z PHP i komunikat jest dość jasny. W pierwszym zapytaniu (Delete) używasz metody prepare, która jest trochę podobna do real_query. Chodzi o to, że wynikiem zapytania, który tutaj nie ma właściwie wyniku w postaci danych jest tylko uchwyt do dalszego opracowywania tego wyniku. Inaczej mówiąc nie można wykonać żadnego następnego zapytania dopóki wynik tego nie zostanie przetworzony (na przykład przesłany lub przygotowany do przesłania, np.: mysqli::use_result()) oraz usunięty np. przez $mysqli_result::free(). Dla innych rodzajów baz metody będą oczywiście inne, ale analogiczne.

Krótko mówiąc zapytanie DELETE nie powinno być wykonywane przez metodę prepare(). W tym celu powinno się użyć np. query() - i to takiej, w której wynik jest od razu oddawany (w przypadku mysql byłoby to użycie query z opcją MYSQLI_STORE_RESULT (domyślnie), zamiast MYSQLI_USE_RESULT). W Twoim przypadku ponieważ używasz obiektu DataBase musisz użyć w pierwszej funkcji query() zamiast prepare(). Albo bawić się w ściąganie i zwalnianie wyniku, którego właściwie nie ma.

I tak na koniec moim zdaniem powinieneś poprawić sobie formatowanie kodu. W takim śmietniku przepuścić można całe stado błędów. Tym bardziej, że to nie java lecz język interpretowany - co oznacza, że błędy pojawią się zawsze w czasie wykonania. Czyli zwykle za późno.

1 użytkowników online, w tym zalogowanych: 0, gości: 1