Forum > Windows CE

Help with TField.AsInteger

(1/2) > >>

ertank:
Hi,

I am using SQLite3 on a WinCE6.0 device. Lazarus version is 1.6

I have below table in one of my databases:

--- Code: ---CREATE TABLE TERMINAL_SAYIM(
 KayitId Integer NOT NULL PRIMARY KEY AUTOINCREMENT,
 AdresKodu Char(30) not null,
 BelgeNo Char(30) not null,
 BelgeTarihi DateTime not null,
 LokasyonKodu Char(30) not null,
 BolgeKodu Char(30) not null,
 GozKodu Char(30) not null,
 SSCC Char(30) not null,
 SSCCKapandi Char(1),
 Barkod Char(30) not null,
 Miktar Integer not null check(miktar > 0),
 OlcuBirimi Char(10),
 Kontrolsuz Char(1) not null,
 TekParca Char(1) not null,
 TekParcaIndex Integer not null,
 TerminalId Char(30),
 KullaniciKodu Char(30),
 OkutmaTarihSaati DateTime NOT NULL,
 SeriNo Char(25),
 Lot Char(25),
 SKT Char(10),
 IslemTuru Char(2),
 Eslesti Char(1),
 Nakledildi Char(1)
);
 
create index Idx_TERMINAL_SAYIM_AdresKodu    on TERMINAL_SAYIM(AdresKodu asc);
create index Idx_TERMINAL_SAYIM_BelgeNo      on TERMINAL_SAYIM(BelgeNo asc);
create index Idx_TERMINAL_SAYIM_LokasyonKodu on TERMINAL_SAYIM(LokasyonKodu asc);
create index Idx_TERMINAL_SAYIM_BolgeKodu    on TERMINAL_SAYIM(BolgeKodu asc);
create index Idx_TERMINAL_SAYIM_GozKodu      on TERMINAL_SAYIM(GozKodu asc);
create index Idx_TERMINAL_SAYIM_SSCC         on TERMINAL_SAYIM(SSCC asc);

--- End code ---

My code below raise an exception saying "" is a invalid integer

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TfrmGiris.ToplamlariGoster(const GenelToplam: Boolean);var  q:TSQLQuery;  CountLokasyon,  CountGoz,  CountSSCC,  CountToplam : Integer;begin  // Eğer ekranda toplam gösterilmeyecek ise işlemciyi yorma  if not lblCount1.Visible then Exit;   CountLokasyon := 0;  CountGoz      := 0;  CountSSCC     := 0;  CountToplam   := 0;   q := TSQLQuery.Create(nil);  try    q.DataBase := DM.OKUMALAR;    q.Transaction := DM.OKUMALAR_Transaction;     // Genel Toplam ise cihaz içindeki toplam kayıt sayısını göster    if GenelToplam then begin      q.SQL.Clear;      q.SQL.Add('select count(miktar) from terminal_sayim');      q.Prepare;      q.Open;      ShowMessage(q.Fields[0].AsString);  // <--- Here I read "0" in the message box when table is empty      CountToplam := q.Fields[0].AsInteger;  // <--- Here I get exception when table is empty    end;  finally    q.Free;  end;end; 
I read from help page about TField.AsInteger and there is this information there:
AsInteger can be used to read or write the contents of the field as a 32-bit signed integer value (of type Integer). If the native type of the field is not an integer value, then an attempt will be made to convert the field value from the native format to a integer value when reading the field's content. Likewise, when writing the property, the value will be converted to the native type of the field (if the value allows it). Therefor, when reading or writing a field value for a field whose native data type is not a 32-bit signed integer-compatible value (string values for instance), an exception may be raised.

I am positive that native data type for my miktar field is Integer, I am assuming count() and sum() native data type is integer, too. Moreover, AsString returns a 0 (zero) as a result. Can anybody advise as to why do I get an exception for my above code when table is empty?

Thanks.

GetMem:
Try this:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  //...  if GenelToplam then  begin    q.SQL.Clear;    q.SQL.Add('select count(miktar) as Total from terminal_sayim'); // or q.SQL.Add('select count(miktar) as "Total" from terminal_sayim');    q.Prepare;    q.Open;    if q.RecordCount > 0 then      ShowMessage(IntToStr(q.FieldByName('Total').AsInteger)) //or q.FieldByName('Total').AsString    else      ShowMessage('No data, empty table!')  end;        //...

ertank:
Hi GetMem,

Actually, I have another workaround. My real intention was to have AsInteger to return zero if that's possible. Delphi function is just fine returning zero if my memory serves me fine.

Btw, my workaround:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---begin    if GenelToplam then begin      q.SQL.Clear;      q.SQL.Add('select count(miktar) from terminal_sayim');      q.Prepare;      q.Open;      TryStrToInt(q.Fields[0].AsString, CountToplam);  end; 
Not to offend you, just my 2 cents: Since application is targeted for WinCE (low CPU and hardware) I am trying to code it to run as fast as possible. "FieldByName" in your suggestion, first searches the field name among active fields. When find it returns index number. Finally the result. So, few ticks slower than "Fields[0]" usage.

This problem I am facing will be only once/twice of the application usage. TryStrToInt will mostly work like IntToStr. Will raise an internal exception (which is controlled in function) very rarely (or none since AsString returns '0'). So, I'm fine with that at the moment.

GetMem:

--- Quote ---Not to offend you, just my 2 cents: Since application is targeted for WinCE (low CPU and hardware) I am trying to code it as fast as possible. "FieldByName" in your suggestion, first searches the field name among active fields. When find it returns index number. Finally the result. So, few ticks slower than "Fields[0]" usage.
--- End quote ---
Don't worry, I don't get offended so easily! :) Since count(miktar) is the only field returned, I doubt q.Fields[0] will be much faster then q.FieldByName(''), but ok I got your point.


--- Quote ---his problem I am facing will be only once/twice of the application usage. TryStrToInt will mostly work like IntToStr. Will raise an internal exception (which is controlled in function) very rarely. So, I'm fine with that at the moment.

--- End quote ---
StrToIntDef will do it just fine, you still should check though why count() returns other then 0 when the table is empty? Is the field null somehow? I just checked(firebird 2.5), count returns 0 even if the table is empty.

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- if SQLQuery1.Fields[0].IsNull then

ertank:
My tests on SQLite shows me returning zero. SqliteBrowser at least returns zero as a result on PC side, too. So, I really do not understand what problem might be.

My real wish is that AsInteger gets an internal control. If is null, return 0.

I can try solving it, too. However, I am kind of lost in details of Lazarus code. If someone knows internals of Lazarus, please direct me to the actual unit & function where I can write a line or two to make it return zero myself.

db.pas lines

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---line 337: function GetAsInteger: Longint; virtual;line 363: procedure SetAsInteger(AValue: Longint); virtual;line 399: property AsInteger: Longint read GetAsInteger write SetAsInteger; 

fields.inc lines

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---line 478: function TField.GetAsInteger: Longint;line 479: line 480: beginline 481:   raise AccessError(SInteger);line 482: end; line 832: procedure TField.SetAsInteger(AValue: Longint);line 833: beginline 834:  raise AccessError(SInteger);line 835: end; 
db.pas lines (linked to AccessError above)

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---line 322: function AccessError(const TypeName: string): EDatabaseError; 
fields.inc lines (linked to AccessError above)

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---line 326: function TField.AccessError(const TypeName: string): EDatabaseError;line 327: line 328: beginline 329:   Result:=EDatabaseError.CreateFmt(SinvalidTypeConversion,[TypeName,FFieldName]);line 330: end; 
All I am seeing is raising an exception code. When I dig deeper, I find Format function in the end and that is main function possibly in one of pre-compiled files I suppose. So, I am stuck trying to fix my own patch of AsInteger since I do not know exactly where to look.

Navigation

[0] Message Index

[#] Next page

Go to full version