Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

How to store an array into a single database field?

Posted on 2011-10-18
5
Medium Priority
?
504 Views
Last Modified: 2012-05-12
I have a 2 dimensional array of enumerated values that are used to represent whether a staff member is willing to work or not on a given weekday in a four week period.
Prefstate = (negative=-1,neutral=0,positive=1);
PrefArray = array[1..4] of array[1..4] of PrefState;

I want to store this array in a single database field of the Staff table, in which each row represents one staff member but  I don’t understand the syntax I need to do this.  I have defined a field in the table as of type BYTE, and reserved 16 bytes (which is the value returned by sizeof(PrefArray)), and internally store the data in a record structure that is defined as:
    StaffRec = record
        Name:String;
        Trauma:boolean;
        GenOnCall:Boolean;
        Preferences : PrefArray;
    end;

var NS: StaffRec;

and after populating the fields attempt to save the data to the dataset:

    srcStaff.DataSet.FieldValues['Preferences'] := NS.Preferences;  
This line does not compile with error ‘E2010 Incompatible types: 'Variant' and 'PrefArray'’.   Typecasting the array as a variant
    srcStaff.DataSet.FieldValues['Preferences'] := variant(NS.Preferences)
compiles, but results in a run time error ‘Invalid variant type or size for field ‘Preferences’’.  

I am using Delphi 2009, and the AbsoluteDB components from Component Ace.

Clearly I am missing something fundamental, and I would be grateful for any help or pointers in the right direction.

0
Comment
Question by:Angus_Crossley
5 Comments
 
LVL 2

Accepted Solution

by:
mensoid earned 1000 total points
ID: 36988793
it's basically telling you the issue, it need the data to be a variant data type not a user defined data type.. I'm not sure id delphi supports it, but in C++ etc you could fake it out but passing the pointer to the array as a pointer to a string which would then be passed to the function looking for a variant after being typecasted. That said I think delphi is too well type checked to allow for this. What you'll have to do is create a set of conversion routines that will convert the array data to a straight string which can be stored. Your also declaring your array as 4X4 I'm thinking you probably want 7X4. It will be slightly more overhead but I think it's your only option.
0
 

Author Comment

by:Angus_Crossley
ID: 36989076
It should be 4x4, as it only refers to Mon to Thu.  The weekend days are treated separately.
0
 
LVL 36

Expert Comment

by:ste5an
ID: 36991173
When you need to store it, then you would store it as BINARY.

BUT: You should really reconsider how you're using your database. Store this information in tables, don't violate 1NF.
0
 
LVL 38

Assisted Solution

by:Geert Gruwez
Geert Gruwez earned 1000 total points
ID: 36992623
small sample of how to convert to a hex string and back
with adding the size of the array as some point of recognition ...
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  paMaxDays = 4;
  paMaxValues = 4;

type
  PrefArray = Array[0..paMaxDays-1, 0..paMaxValues-1] of byte;

  TfrmTestEE = class(TForm)
    btnFillArray: TButton;
    Memo1: TMemo;
    btnConvertToString: TButton;
    btnConvertToArray: TButton;
    procedure btnFillArrayClick(Sender: TObject);
    procedure btnConvertToStringClick(Sender: TObject);
    procedure btnConvertToArrayClick(Sender: TObject);
  private
    fPrefArray: PrefArray;
    fPrefArrayString: string;
    procedure ShowArray(Msg: string);
  end;

var
  frmTestEE: TfrmTestEE;

implementation

uses StrUtils;

{$R *.dfm}

procedure TfrmTestEE.ShowArray(Msg: string);
var
  I: Integer;
  J: Integer;
  mem: TMemo;
  line: string;
begin
  mem := Memo1;
  mem.Lines.Add('Array fPrefArray -- ' + Msg);
  for I := 0 to paMaxDays - 1 do
    for J := 0 to paMaxValues - 1 do
      mem.Lines.Add(Format('[%d, %d] = %d', [I+1, J+1, fPrefArray[I, J]]));
  mem.Lines.Add('');
  mem.Lines.Add('Array view : ');
  for I := 0 to paMaxDays - 1 do
  begin
    line := '';
    for J := 0 to paMaxValues - 1 do
      line := line + Format('%3.3s', [IntToStr(fPrefArray[I, J])]) + IfThen(J<paMaxValues-1,', ','');
    mem.Lines.Add('[' + line + ']');
  end;
  mem.Lines.Add('-----------------');
  mem.Lines.Add('');
end;

procedure TfrmTestEE.btnConvertToArrayClick(Sender: TObject);
  function HexToIntDel(var s: string; digits: integer = 0): integer;
  begin
    try
      if digits >0 then
      begin
        Result := StrToInt(HexDisplayPrefix + Copy(S, 1, digits));
        Delete(S, 1, digits);
      end else
        Result := StrToInt(HexDisplayPrefix + S);
    except
      Result := 0;
    end;
  end;
var
  s: string;
  MaxDays, MaxValues, I, J: integer;
begin
  s := fPrefArrayString;
  MaxDays := HexToIntDel(S, 2);
  MaxValues := HexToIntDel(S, 2);
  if (MaxDays <> paMaxDays) or (MaxValues <> paMaxValues) then
    Memo1.Lines.Add(Format('Expecting dimensions [%d, %d] but dimensions [%d, %d] found.',
      [paMaxDays, paMaxValues, MaxDays, MaxValues]))
  else
  begin
    for I := 0 to MaxDays - 1 do
      for J := 0 to MaxValues - 1 do
        fPrefArray[I, J] := HexToIntDel(s, 2);
    ShowArray('Rebuild array');
  end;
end;

procedure TfrmTestEE.btnConvertToStringClick(Sender: TObject);
var
  s: string;
  I, J: integer;
begin
  s := '';
  s := Format('%.2x%.2x', [paMaxDays, paMaxValues]);
  for I := 0 to paMaxDays - 1 do
    for J := 0 to paMaxValues - 1 do
      s := s + Format('%.2x', [fPrefArray[I, J]]);
  memo1.Lines.Add(s);
  fPrefArrayString := s;
end;

procedure TfrmTestEE.btnFillArrayClick(Sender: TObject);
var
  I: Integer;
  J: Integer;
begin
  for I := 0 to paMaxDays - 1 do
    for J := 0 to paMaxValues - 1 do
      fPrefArray[I, J] := Random(255);
  ShowArray('Fill array');
end;

end.

Open in new window


i assume you know how to store and retrieve a string from the database ... :)
0
 

Author Closing Comment

by:Angus_Crossley
ID: 36994357
Thanks experts.
0

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What we learned in Webroot's webinar on multi-vector protection.
This is an update to some code that someone else posted on Experts Exchange. It is an alternate approach, I think a little easier to use, & makes sure that things like the Task Bar will update.
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

572 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question