Aus Excel exportierte Daten mit Bestandsdaten vergleichen und Änderungen übernehmen

Alles klar, dann bleibt's bei ADODB ;-)

Ok, nächste Frage: Der Query, der an die Execute()-Methode übergeben wird, ist das ein Statement mit Placeholder - also etwas in der Art "SELECT * FROM foo WHERE bar = :val" ?

Woher weißt du, das der Query an der DB ausgeführt wurde, wenn der zweite Logger-Eintrag nicht auftaucht? Oder sprechen wir bei "zweiter Logger" von

PHP:
logger(" Method: ".__METHOD__."", "Query Executed",LOG_LEVEL_DEBUG);

oder

PHP:
logger(" Method: ".__METHOD__."", "AppID: ".$res->ID,LOG_LEVEL_DEBUG);

Liefert der Query von Zeile 2 deines Code-Ausschnitts tatsächlich ein gefülltest oder eher ein leeres Result? Hast du vor der Zeile

PHP:
$recordSet->FetchNextObject()

mal

PHP:
logger(" Method: ".__METHOD__.":".__LINE__, "ResultCount: ".$recordSet->ResultCount(),LOG_LEVEL_DEBUG);

geloggt? Einfach, um sicher zu sein, das die while() auch mindestens einmal durchlaufen wird.
 
Hi,

da habe ich mich wohl nciht ganz klar ausgedrückt. Der logger Eintrag mit "Query Executed" wird nicht mehr erreicht. Der Query selbst ist grundsätzich "lauffähig". Wenn ich diesen aus dem Log in den SQL Debuger kopiere, dann läuft dieser sauber durch. Der Query hat keine Placeholder - dafür aber 7 left outer joins und einen inner join der seinerseits einen sub query ausführt...
 
Ok, kein Ding, dafür kann ich ja Fragen stellen ;-)

Was genau ist im Statement $query? Ist das evtl. ein Statement, das aus Variablen zusammen gebaut wird, oder ist eine konstante Zeichenkette? Wenn es mit Variablen ist, hast du mal versucht, ein PreparedStatement statt dessen zu verwenden? ADODB bietet diese Möglichkeit ja an: http://phplens.com/adodb/reference.functions.prepare.html

Befindet sich der gezeigte Code-Ausschnitt widerum in einer Schleife? Wenn ja wie oft wird die Schleife durchlaufen?

Dann was grundsätzliches: Hast du schon, wie alxy empfohlen hat, geprüft, ob display_errors auf 1 steht und ggf. mal mittels ini_set() umgestellt?

Vllt. kommst du dir mittlerweile veralbert vor, aber ich kenne deine Kenntnisse nicht, daher diese "primitiven" Fragen.
 
Hi,

der primäre query ist statisch - der subquery enthält einige variable Werte. Die Prepare Statement Geschichte bringt (zumindest laut der doku) keine Performance Vorteile - daher habe ich diesen Weg bis jetzt nicht gewählt. Wenn der SubQuery nicht so dynamisch wäre, hätte ich das ganze schon in eine Stored Precedure geworfen...

Der Code Ausschnitt befindet sich in keiner Schleife und der Query wird nur ein Mal ausgeführt. Display_errors ist on - habe ich auch schon über die phpinfo geprüft.

... komme mir nicht veralbert vor, habe über die Jahre gelernt, dass die Fehler meistens an Stellen liegen an denen man sie nicht vermutet... Kenntnisse sollte ich an sich recht viele haben. Ich bin einer der Tech-Admins der Plattformen in meiner Signatur und schreibe daher auch des öfteren eigene Plugins. Frag also ruhig weiter - wenn das zu einer Lösung fürht lohnt es sich auf jeden Fall.

Ich werde am WE mal als "Backup" die Logik der Klasse etwas umstellen und etwas mehr Last auf die Datenbank verlagern. Derzeit fahre ich vereinfacht folgenden Weg:

DB - Struktur

Tabelle_1
T1_ID
T1_Name

Tabelle_2
T2_ID
T2_Name

Tabelle_3_T1_T2
T1_ID
T2_ID

Objekt:
PHP:
class Objekt1 {
  public $ID
  public $Name
  public $Objects2 = array(); // Type of Objekt2
}

class Objekt2 {
  public $ID
  public $Name
}

Abfrage:
PHP:
$query = "
SELECT 
  A.ID, 
  A.NAME 
FROM 
  Tabelle_1 A
LEFT OUTER JOIN
  Tabelle_3_T1_T2 B
ON
A.T1_ID = B.T1_ID
LEFT OUTER JOIN
  Tabelle_2 C
ON
B.T2_ID = C.T2_ID";
logger(" Method: ".__METHOD__." 002",$query,LOG_LEVEL_DEBUG);
$recordSet  = $GLOBALS['adodb']->Execute($query);
logger(" Method: ".__METHOD__."", "Query Executed",LOG_LEVEL_DEBUG);
if (!$recordSet) ErrorReport("Class:".__CLASS__." Method: ".__METHOD__." ", $GLOBALS['adodb']->ErrorMsg().$query, true);
$this->List = array();
while($res = $recordSet->FetchNextObject()) {
	if(!isset($this->List[$res->T1_ID])) {
		$obj = NEW Objekt1(); 
		$obj->ID = stripslashes($res->T1_ID);
		$obj->Name = stripslashes($res->T1_NAME);
		$this->List[$res->T1_ID] = $obj;
	}
	if(!isset($this->List[$res->T1_ID]->Objects2[$res->T2_ID])) {
		$obj2 = NEW Objekt2(); 
		$obj2->ID = stripslashes($res->T2_ID);
		$obj2->Name = stripslashes($res->T2_NAME);
		$this->List[$res->T1_ID]->Objects2[$res->T2_ID] = $obj2;
	}
}

return $this->List;

...
 
Prinzipiell geht es da erst mal nicht um Performance, sondern eher darum, das eine Variable im Query bspw. als String behandelt wird, der Typ der Table-Column aber bspw. Integer ist (oder umgekehrt, solche Dinge halt). Ein PreparedStatement würde hier Abhilfe schaffen, da man im Query nicht zwischen Int oder Varchar (Text, Blob, $whatever) unterscheiden muss, der RDBM-Server kümmert sich selbst darum. Ich hab schon einiges gesehen, und manchmal sind es solche Kleinigkeiten wie ein Single-Quote um Daten, die eigentlich ein Integer oder Double sind.

Meine Frage bezüglich der Schleife zielt darauf ab, dass es ratsam ist, bei Schleifen die ResultSets freizugeben, um damit Speicher zu sparen. Dies kann man laut Doku auch mit $recordSet->Close() erreichen, dürfte aber in diesem Falle keine Lösung für das Problem sein, da du ja schon schreibst, das es keine Schleife ist.

Weitere Möglichkeiten: Hast du schon Webserver-Logs konsultiert, ob du evtl. einen Bug in der ADODB hast, der ein SEGFLT resultiert? Solche Meldungen würden über HTTP nicht ausgegeben, da Apache ein Child tötet, das einen Segfault verursacht. Anderenfalls steht evtl. im Webserver-Log etwas aufschlussreicheres, als nichts ;-)

Hast du den statischen Query mal in einem einfachen Kontext ausprobiert, sprich einen 3-Zeiler (Datenbank-Verbindung aufbauen, Query senden und Results abholen)?

Ich würde dennoch mal den PS-Weg ausprobieren, vielleicht liefert es mal Fehlermeldungen statt einfach "wegzubrechen".
 
Zurück