Hallo !
Ich habe ein kleines Problem beim Speichern binärer Daten in einer MSSQL-Datenbank.
Aufgabenstellung ist es .pdf- bzw .doc dateien binär in der Datenbank abzulegen.
Hierzu habe ich folgenden Code geschrieben (vereinfacht):
Das funktioniert soweit einwandfrei, die Daten lassen sich auch problemlos auslesen und wieder als Datei (mit entsprechendem MIME-Type) anzeigen.
Problem:
Die zu speichernden Dateien können manchmal auch relativ groß sein (3-10MB), was dazu führt das PHP das Script mit dem FATAL ERROR: allowed memory size exhausted abbricht.
Pfiffig wie ich bin ;-) war mein Lösungsansatz für dieses Problem die Dateien nicht auf einmal in die Datenbank zu schreiben, sondern sie stückweise einzulesen.
Alles wunderbar, das Script wird nicht mehr abgebrochen und Daten werden in die Datenbank geschrieben.
Allerdings werden die Daten bei diesem Vorgang zerstört bzw verändert, so das ich sie nicht mehr korrekt auslesen kann.
Ich kann aber den Fehler der zur fehlerhaften Speicherung führt nicht lokalisieren.
Zum einen könnte ich mir vorstellen, dass MSSQL die binären Daten beim Speichern anpasst und es beim verketten mit den neuen Daten zu einem Fehler kommt. (i.d.R wird der zuerst eingefügte teil korrekt ausgegeben) Und auch die hin und her Konvertierung der Daten ist natürlich eine Fehlerquelle.
Zum Anderen könnte ich mir auch vorstellen, dass die _gesonderte Codierung_ der einzelnen Teilstrings in base64 die Daten die letzendlich in der Datenbank stehen verändert.
Hier der Code der die Daten in die Datenbank schreibt(wieder Beispielcode der Einfachheit halber):
Wenn ich nun die Daten ausgebe sind sie zerstört, dh. die Rückgabedaten weichen von den Eingabedaten ab.
Meine Frage ist nun:
Hat jemand eine Idee was für zur Veränderung der Daten führt?
(Vielleicht sind es ja auch mehre Fehlerquellen)
Mein persönlicher Eindruck ist das die Daten durch die stückweise Codierung mit base64 verändert werden. Aber warum? Und wie kann ich diesen Fehler beheben/ausgleichen?
Ergänzung:
PS: mir ist durchaus bewußt, dass man Files nicht in die Datenbank steckt, aber mein "Kunde" akzeptiert nur diese Lösung. Mir wär es auch lieber die Daten im Filesystem abzulegen. Also bitte ich euch nur das hier beschriebene Problem zu diskutieren - insofern das jemand möchte ;-)
Schon mal im Voraus Danke für eure Hilfe!
Ich habe ein kleines Problem beim Speichern binärer Daten in einer MSSQL-Datenbank.
Aufgabenstellung ist es .pdf- bzw .doc dateien binär in der Datenbank abzulegen.
Hierzu habe ich folgenden Code geschrieben (vereinfacht):
Code:
// File wird geöffnet und Inhalt in Variable gespeichert $fh = $fopen("pdfdokument.pdf","rb"); $filedata = fread($fh, filesize("pdfdokument.pdf")+1); // File wird in base64 codiert um ihn mit der SQL-Query auszuführen $base64data = base64_encode($filedata); // File in Datenbank speichern $sql = "INSERT INTO files (data) VALUES (CONVERT(varbinary(max),CONVERT(varchar(max),$base64data))"; $res = mssql_query($sql);
Problem:
Die zu speichernden Dateien können manchmal auch relativ groß sein (3-10MB), was dazu führt das PHP das Script mit dem FATAL ERROR: allowed memory size exhausted abbricht.
Pfiffig wie ich bin ;-) war mein Lösungsansatz für dieses Problem die Dateien nicht auf einmal in die Datenbank zu schreiben, sondern sie stückweise einzulesen.
Alles wunderbar, das Script wird nicht mehr abgebrochen und Daten werden in die Datenbank geschrieben.
Allerdings werden die Daten bei diesem Vorgang zerstört bzw verändert, so das ich sie nicht mehr korrekt auslesen kann.
Ich kann aber den Fehler der zur fehlerhaften Speicherung führt nicht lokalisieren.
Zum einen könnte ich mir vorstellen, dass MSSQL die binären Daten beim Speichern anpasst und es beim verketten mit den neuen Daten zu einem Fehler kommt. (i.d.R wird der zuerst eingefügte teil korrekt ausgegeben) Und auch die hin und her Konvertierung der Daten ist natürlich eine Fehlerquelle.
Zum Anderen könnte ich mir auch vorstellen, dass die _gesonderte Codierung_ der einzelnen Teilstrings in base64 die Daten die letzendlich in der Datenbank stehen verändert.
Hier der Code der die Daten in die Datenbank schreibt(wieder Beispielcode der Einfachheit halber):
Code:
$filesize = filesize("pdffile.pdf"); $temp_filesize = $filesize/4; $i = 0; while(!feof($fh)) { $filedata = fread($fh,$temp_filesize+1); $base64data = base64_encode($filedata); if($i==0){ $sql = "INSERT INTO files (data) VALUES ( CONVERT(varbinary(max), CONVERT(varchar(max),'$base64data')) ); SELECT @@identity AS last_id"; // Abfrage und Ergebnistest $id = $row['last_id']; } else{ $sql = "UPDATE files SET data=CONVERT(varbinary(max), CONVERT(varchar(max),data)+CONVERT(varchar(max),'$base64data')) WHERE id=$id"; // Abfrage und Ergebnistest } $i++; }
Meine Frage ist nun:
Hat jemand eine Idee was für zur Veränderung der Daten führt?
(Vielleicht sind es ja auch mehre Fehlerquellen)
Mein persönlicher Eindruck ist das die Daten durch die stückweise Codierung mit base64 verändert werden. Aber warum? Und wie kann ich diesen Fehler beheben/ausgleichen?
Ergänzung:
Code:
-- testtabelle CREATE TABLE( id int IDENTITY(1,1), data varbinary(max), CONSTRAINT pk PRIMARY KEY (id) );
Schon mal im Voraus Danke für eure Hilfe!
Comment