Buff binaires et blobs

solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 - 29 mai 2011 à 00:47
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 - 31 mai 2011 à 18:46
Bonsoir tous,
Je ne suis pas fier de vous demander ca depuis le temps que je "bricole" avec D. Mais vous êtes là pour ça, merci. Le prob:
Une db Firebird.
1 - je veux mettre dans un champs string/memo/blob (?) des donnéées binaires de longueur variable:
type
ty_0151 = record
ref : string[16];
data : array[0..1024] of char;
end;
ty_0152 = record
ref : string[16];
data : array[0..1000000] of char;
end;
ty_0154 = record
ref : string[16];
ref2 : string[16];
Nbxx : integer;
data : array[0..1000000] of char;
end;

var v_0151 : ty_0151;
v_0152 : ty_0152;
tb_0154 : array[1..10] of ty_0154;

et ainsi de suite ... dans une table:
create table tReglage (
Id integer not null,
TypRec varchar(6),
ref varchar(16),
LenData integer,
MonRec blob(80,0) // contient tout le rec y compris ref
);
Je ne suis pas foutu de transférer mes records dans mon blob. Utiliser les memo/blob via des controles image/tMemo/tRich ok, mais manipuler Rec<=>table je ne trouve pas.
(shame on me)

2 - 1 est réglé, merci les gars.
Je veux, via tQuery afficher ma table (select where TYPREC = :XXX) en créant des champs calculés issus de mon blob (oncalcfield).
- un booleen pos 1260 dans un dbcheckbox
- une chaine issue de pos 27..132
- un double en pos 612 et ainsi de suite.
Tout ca facile si je sais lire mon blob et le mettre dans mes records pour le oncalcfiels.

3 - mettre à jour mon record et donc le blob via saisie dans un dbGrid des mes champs calcules (le boolean, la chaine, double ...)
Tout ca je sais faire si je sais comment mover ty_0151 <=> blob.
J'ai juste besoin des methodes pour initialiser le blob/memo/string à xxxx octets et le lire / ecrire. Le reste devrait aller
Merci à tous.

solilog

6 réponses

cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
30 mai 2011 à 14:28
Bonjour,

voir fonction SUBSTRING si elle existe dans ta version de Firebird,
directement utilisable en SQL.


cantador
0
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
30 mai 2011 à 17:24
Bonjour Cantador,
Je pensais bien que ce serait toi qui repondrait le 1er. Mais tu ne resouds pasmon probleme. SubStr je connais bien sûr.
1 : Substr bien-sur que cette fonction existe, mais ne marche pas sur un blob. Et sans SQL, en Delphi je fais comment ?
2 : avant de lire le blob je voudrais bien l'ecrire.
Avec une chaine je fais fields[x].asstring := maStr;
integer fields[x].asstring := monInt;
Mais un blob je fais comment fields[x].??????? := monrecord ?
Merci quand meme.

solilog
0
cs_cantador Messages postés 4720 Date d'inscription dimanche 26 février 2006 Statut Modérateur Dernière intervention 31 juillet 2021 13
31 mai 2011 à 12:10
je savais que j'avais quelque chose dans mon fourbis...

voilà un source utilisant les packed record :
unit main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, Grids, DBGrids, ComCtrls;

type

TUser = packed record
Name : string[50];
CanAsk : boolean;
NumberOfQuestions : integer;
end;


TRecord2BlobForm = class(TForm)
DBGrid1: TDBGrid;
ADOConnection1: TADOConnection;
DataSource1: TDataSource;
edName: TEdit;
chkCanAsk: TCheckBox;
InsertButton: TButton;
myTable: TADOTable;
UpDown1: TUpDown;
edNOQ: TEdit;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure InsertButtonClick(Sender: TObject);
procedure myTableAfterScroll(DataSet: TDataSet);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Record2BlobForm: TRecord2BlobForm;

implementation

{$R *.dfm}

procedure TRecord2BlobForm.myTableAfterScroll(DataSet: TDataSet);
var
User : TUser;
blobF : TBlobField;
bs : TStream;
begin
if myTable.State in [dsInsert] then Exit;

if myTable.FieldByName('data').IsBlob then
begin
blobF := DataSet.FieldByName('data') as TBlobField;
bs := myTable.CreateBlobStream(blobF, bmRead);
try
bs.Read(user,sizeof(TUser));
finally
bs.Free;
end;
end;

edName.Text := User.Name;
edNOQ.Text := IntToStr(User.NumberOfQuestions);
chkCanAsk.Checked := User.CanAsk;
end;

procedure TRecord2BlobForm.InsertButtonClick(Sender: TObject);
var
User : TUser;
blobF : TBlobField;
bs : TStream;
begin
User.Name := edName.Text;
User.NumberOfQuestions := StrToInt(edNOQ.Text);
User.CanAsk := chkCanAsk.Checked;

myTable.Insert;

myTable.FieldByName('id').AsInteger := GetTickCount;

blobF := myTable.FieldByName('data') as TBlobField;
bs := myTable.CreateBlobStream(blobF, bmWrite);
try
bs.Write(User,SizeOf(User));
finally
bs.Free;
end;

myTable.Post;
end;

procedure TRecord2BlobForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
myTable.Close;
end;

procedure TRecord2BlobForm.FormCreate(Sender: TObject);
begin
myTable.Open;
end;

end.

intéressant non ???

ahhh pas encore zut ..
je fais une sieste..

cantador
0
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
31 mai 2011 à 12:13
Salut Cantador,
Non pas papa solilog, on peut dire pappy maintenant. Bon passons.
Si j'ai SQL mais comment faire insert ... On fait des insert à partir d'autres tables, là je veux creer une table avec mes data.

Reprenons. J'ai un record
type MyRec record
Ref : string[16],
data : array[0..10000] of char;
end;

var MyVar : MyRec;

- comment mettre ce record dans un tBlobfield de nom DATA ? (lecture)
Table.edit;
matable.fieldbyname('DATA').?????? = MyVar;
ou faire un move ?

- comment mettre ce tBlobfield dans mon record ? (ecriture)
move ( , MyRec, sizeof(myrec));

Merci
solilog
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
31 mai 2011 à 12:17
Oups cantador pardon,

J'ai repondu sans voir que tu as repondu plusieurs fois.
Je lis la fin et reviens.
solilog
0
solilog Messages postés 273 Date d'inscription samedi 13 juin 2009 Statut Membre Dernière intervention 18 avril 2015 10
31 mai 2011 à 18:46
Re bonjour,
Donc ca marche. En utilisant des les champs tblobfield et un stream. Ok, merci.
C'est quand même un peu lourd.
Y a pas d'autres moyens de lire/ecrire un blob (ou tblobfield) sans passer par un stream ? On lui assignerait une longueur suivie d'un move(src, dest, lng) ? chiant le mec! J'attends qq'jours pour fermer la question, si qq'1 avait un moyen plus simple.

Merci beaucoup cantador en attendant je vais utiliser ta solution.

solilog
0
Rejoignez-nous