Blobverarbeitung in php

Forum für Fragen rund um Firebird-Software von Drittanbietern.

Moderator: martin.koeditz

Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hi Volker,

habe ich auch nicht als Affront verstanden.

Du hast bei langen Texten wirklich nur die Chance einen VARCHAR zu verwenden oder einen BLOB. Wenn du BLOBs verwendest, müssen die fbird_ bzwl. ibase-Funktionen hinzugefügt werden. Da geht kein Weg dran vorbei.

Nachdem ich mit der FB 4.0-Übersetzung durch bin, werde ich mal sehen, ob ich die PHP-Doku etwas auffrischen kann.

Gruß
Martin
Martin Köditz
it & synergy GmbH
vr2
Beiträge: 214
Registriert: Fr 13. Apr 2018, 00:13

Hi Martin,

die Docs zum Dunstkreis BLOBs sind auch anderswo mager. Zb heißt es hier https://www.firebirdsql.org/file/docume ... s-api.html
- BLOBs can now be moved to or from different types in the execute and fetch calls.
- For input parameters, it allows a parameter to be put as a string without the need to create and fill a BLOB from the client side.
Schon mal eine Aussage, aber es wird nicht gesagt, welche Limits gelten und welche Konsequenzen der Ansatz hat. In der Doku zu IBX bspw erfährt man mehr:
7.7 Inline Blobs
A Firebird Blob is stored in separate database pages from the table from which it is referenced. Only the Quad word BlobID is stored in the database column. Normally, a blob is saved to the database as a separate interaction to the update/insert used to save the table row from which the blob is referenced. The blob is saved, the Blobid returned and this is used as the column value. This incurs a significant extra overhead and sometimes for relatively small amounts of data. Often a blob is used to store (e.g.) plain text that can vary in size from a single sentence to a complete book.

Firebird does not require that the SQL type of a query parameter matches the SQL Type of the column being updated. The query will succeed as long as the data can be converted to the column's SQL Type. For example, a numeric value can be passed as a string and then converted to an actual numeric when it reaches the server.

This feature is exploited by the Firebird Pascal API to support inline blobs. Here, an inline blob is simply a text string. The parameter's .SetAsString method is used to set the value of a Blob column to a string variable. The string text is then passed to the server when the update/insert is executed and converted to a blob on receipt. Even binary blobs can be handled in this way - these are transferred to the server using the OCTETS string type to avoid any transliteration issues.

For example, consider a table defined by:

Code: Alles auswählen

Create Table BLOBTEST(
Rowid integer not null,
MyText Blob sub_type 1,
Primary Key (Rowid)
);
and with the following insert statement:

Code: Alles auswählen

INSERT INTO BLOBTEST(Rowid,MyText) Values(:Rowid,:MyText);
The following pascal code inserts a row using an inline blob for MyText:

Code: Alles auswählen

var Statement: IStatement;
{assume that MyAttachment and MyTransaction exist and have been correctly created}
begin
Statement := MyAttachment.Prepare(myTransaction,'the above insert statement');
Statement.SQLParams.ByName('Rowid').AsInteger := 1;
Statement.SQLParams.ByName('MyText').AsString := 'This is a test';
Statement.Execute;
Note: From Firebird 4.0 onwards, the underlying Firebird API also provides an inline blob capability specific to batch updates. This is not the same as the above mechanism.

If the text is longer than 8192 bytes (default) then the API will create a blob on your behalf and save the blob id as the column value. This is to avoid excessively large messages. This default can be overridden using the IAttachment.SetInlineBlobLimit method (see 4.12).

Note: Firebird imposes a maximum string length of 32KB. Inline blobs can be problematic with segmented blobs.
Soweit der Pascal-Firebird-Treiber. Das 32K-String-Limit findet sich auch den Quellen des Treibers, SetInlineBlobLimit sorgt dafür, dass dieses Limit eingehalten wird. Man weiß nun, dass man Textblobs beliebiger Größe als Parameter übergeben kann, ohne die Längennmessung selbst machen zu müssen und ohne explizit ein Blobobjekt anzulegen zu müssen. Das macht das API intern, wenn der Wert des InlineBlobLimits überschritten ist. Und das Ganze geht selbstverständlich auch mit Binärblobs.

Damit weiß man, was Sache ist. In der Konsequenz braucht man die expliziten Blobfunktionen zum Schreiben häufig nicht mehr. Zur vollständigen Einordnung fehlt nur noch der Hinweis auf die max Statementgröße 64K (bis FB25 ) bzw 10MB (ab FB3), die bei FB25 schnell erreicht wird, wenn man mehrere Blobfelder hat und die alle knapp unterhalb 32K parametrisiert werden. Richtung alte Firebirdserver verpackt man die also besser selber.

Grüße, Volker
Antworten