AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Denkblockade: Wie speicher ich ein Array in einer Datenbank?
Thema durchsuchen
Ansicht
Themen-Optionen

Denkblockade: Wie speicher ich ein Array in einer Datenbank?

Ein Thema von Mithrandir · begonnen am 3. Mai 2009 · letzter Beitrag vom 7. Mai 2009
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#11

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 20:52
Hmm... WriteLN kann man aber nicht direkt für TStream nutzen, oder? Bei mir kommt immerhin die Meldung:

Zitat:
[Pascal Fehler] ORP_DataBase.pas(232): E2054 Ungültiger Typ in Write/Writeln-Anweisung
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#12

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 21:02
Und mit Write()?
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#13

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 21:09
Genau dasselbe. Außerdem ist mir eingefallen, dass ich die Strings in der Länge begrenzen muss. Sonst weiß ich ja gar nicht, wo was anfängt und aufhört, wenn ich das ganze wieder auslesen will, oder?
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.851 Beiträge
 
Delphi 11 Alexandria
 
#14

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 21:20
Versuche es mal mit einem Zwischen-Stream.

String -> StringStream -> BlobStream -> Datenbankfeld
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#15

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 21:30
Zitat von mkinzler:
Versuche es mal mit einem Zwischen-Stream.

String -> StringStream -> BlobStream -> Datenbankfeld
Weißt du aus dem Kopf, ob folgende Idee auch klappen könnte?

Delphi-Quellcode:
//Größe des Records dank String[] bekannt
TORPTag = packed record
     Key: String[255];
     Value: String[255];
  end;

  TORPTags = Array of TORPTag;

procedure WriteToDB(Tags: TORPTags);
var
 MemoryStream: TMemoryStream;
 i: integer;
begin
 MemoryStream := TMemoryStream.Create;
//...
 for i := Low(Tags) to High(Tags) do
  MemoryStream.Write(Tags[i], Sizeof(TORPTags));
//...
end;
Ich kanns grad leider nicht überprüfen...

//Edit: Oder müsste dann das "Packed" raus?
//Edit2: Ist mal eben so aus dem Kopp getippt...
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#16

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 21:45
Das kann man ja nich mit ansehen
Delphi-Quellcode:
type
  TTag = record
    Key, Value: string;
  end;

  TTags = array of TTag;

procedure WriteInt(i: Integer; stream: TStream);
begin
  stream.Write(i, sizeof(i));
end;

function ReadInt(stream: TStream): Integer;
begin
  stream.Read(result, sizeof(result));
end;

procedure WriteString(s: string; stream: TStream);
begin
  WriteInt(Length(s), stream);
  stream.Write(s[1], Length(s));
end;

function ReadString(stream: TStream): string;
begin
  SetLength(result, ReadInt(stream));
  stream.Read(result[1], Length(result));
end;

procedure WriteTags(tags: TTags; stream: TStream);
var i: Integer;
begin
  WriteInt(Length(tags), stream);
  for i := 0 to High(tags) do begin
    WriteString(tags[i].Key, stream);
    WriteString(tags[i].Value, stream);
  end;
end;

function ReadTags(stream: TStream): TTags;
var i: Integer;
begin
  SetLength(result, ReadInt(stream));
  for i := 0 to High(Result) do begin
    tags[i].Key := ReadString(stream);
    tags[i].Value := ReadString(stream);
  end;
end;
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#17

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 3. Mai 2009, 21:48
Zitat von Dax:
Das kann man ja nich mit ansehen
Ist das mit mir wirklich so ein Trauerspiel? Ich weiß, ich konnt's mal besser...

Danke
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#18

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 7. Mai 2009, 10:30
Dax,

irgendwie funktioniert ein Teil deines Code nicht. Wenn ich mit ReadTags die Tags auslesen möchte, dann alloziiert er im ersten Durchlauf ~600 MB, den zweiten Durchlauf schafft er gar nicht mehr, weil er dann nicht genug Arbeitsspeicher hat.

Wenn ich mir diese Funktion ansehe, dann sollte man meinen, dass er 4 Byte liest:

Delphi-Quellcode:
function TORPDataBase.ReadInt(Stream: TMemoryStream): Integer;
begin
  stream.Read(result, sizeof(Integer));
end;
Stattdessen springt der Speicherverbrauch auf 600 MB...

[edit=mkinzler]Delphi-Tag eingefügt Mfg, mkinzler[/edit]
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#19

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 7. Mai 2009, 14:05
Vorweg: natürlich kann ich mich hinsichtlich der APIs irren, aber ich glaube, dass Read und Write Parameter (Pointer,Länge) hatten

Ich bezweifle aber stark, dass es an der Methode liegt. Tritt das Problem denn immer auf, oder erst ab einer gewissen Tagmenge?
  Mit Zitat antworten Zitat
Benutzerbild von Mithrandir
Mithrandir
(CodeLib-Manager)

Registriert seit: 27. Nov 2008
Ort: Delmenhorst
2.379 Beiträge
 
#20

Re: Denkblockade: Wie speicher ich ein Array in einer Datenb

  Alt 7. Mai 2009, 14:34
Zitat von Dax:
Vorweg: natürlich kann ich mich hinsichtlich der APIs irren, aber ich glaube, dass Read und Write Parameter (Pointer,Länge) hatten

Ich bezweifle aber stark, dass es an der Methode liegt. Tritt das Problem denn immer auf, oder erst ab einer gewissen Tagmenge?
Hi,

ja, das Verhalten tritt immer auf.

So schreibe ich die Knoten und die dazugehörigen Tags in die Datenbank:

Delphi-Quellcode:
procedure TORPDataBase.WriteNodeToDB(Node: TORPNode);
var
  Blob: TMemoryStream;
begin
  Blob := TMemoryStream.Create;
  Blob.Seek(0,soFromBeginning);
  try
    DecimalSeparator := '.';
    with fInsertNodeQuery do
    begin
      Connection := fConnection;
      ParamCheck := true;

      WriteTags(Node.tags, Blob);

      Params.CreateParam(ftBlob, 'tags', ptInput);
      ParamByName('tags').LoadfromStream(Blob, ftBlob);

      ParamByName('lon').AsFloat := StrToFloat(Node.Lon);
      ParamByName('lat').AsFloat := StrToFloat(Node.Lat);
      ParamByName('node_id').AsInteger := StrToInt(Node.ID);
      ExecSQL;
    end;
  finally
    FreeAndNil(Blob);
  end;
end;
Und so lese ich sie wieder aus:

Delphi-Quellcode:
function TORPDataBase.ReadNodesFromDB(): TORPNodes;
var
  BlobStream: TStream;
  Blob: TMemoryStream;
  fSelectNodeQuery: TZQuery;
  i: integer;
begin
  try
    DecimalSeparator := '.';
    fSelectNodeQuery := TZQuery.Create(nil);
    with fSelectNodeQuery do
    begin
      Connection := fConnection;
      ParamCheck := true;
      SQL.Text := 'SELECT * FROM NODES';
      Open;
      While not fSelectNodeQuery.Eof do
      begin
        Blob := TMemoryStream.Create;
        Blob.Seek(0,soFromBeginning);

        SetLength(Result,Length(Result)+1);
        i := High(Result);

        Result[i].ID := FieldByName('ID').AsString;
        Result[i].Lat := FieldByName('Lat').AsString;
        Result[i].Lon := FieldByName('Lon').AsString;

        BlobStream := CreateBlobStream(FieldByName('Tags'),bmRead);

        try
          Blob.CopyFrom(BlobStream, 0);
        finally
          FreeAndNil(BlobStream);
        end;

        Result[i].Tags := ReadTags(Blob);

        fSelectNodeQuery.Next;
      end;
    end;
  finally
    FreeAndNil(Blob);
  end;
end;
Jede wette, da steckt nur irgendein kleiner dämlicher Fehler drin?

Ich hatte tatsächlich die Tags vergessen? Oh man..
米斯蘭迪爾
"In einer Zeit universellen Betruges wird das Aussprechen der Wahrheit zu einem revolutionären Akt." -- 1984, George Orwell
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:43 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz