Why not simplySame issue.
s := BufDataset1.FieldByName('Str5Field').AsString;
?
RecCount=0
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=
In addition to Zvoni's findings:Yes, it's the reason why i left out bd.free in above code (and i don't care about memory-leaks when just testing around and it's basically the end of the program anyway)
- it leaks memory
- it creates an access violation when not using a exception block to free the instantiated class.
The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)Was my first thought, too, but doesn't make a difference if you shorten the String to "ABCDE" - same issue.
That really messes things up.
Just define the stringfield as a field of 20 characters and the code should work fine.
// bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8); bd.FieldDefs.Add('Str5Field', ftString, 20);
And what happens if you use this??The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)Was my first thought, too, but doesn't make a difference if you shorten the String to "ABCDE" - same issue.
That really messes things up.
Just define the stringfield as a field of 20 characters and the code should work fine.
// bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8); bd.FieldDefs.Add('Str5Field', ftString, 20);
Just try it.
Yes, i wondered about that, too (since when do you need precision for Strings?!?!), but i think OP used this overloaded function because of the following params after precision (required, readonly, codepage)And what happens if you use this??The problem might be that you are trying to stuff a string of 7 characters "ABCDEFG" in a field defined with Size = 5 !! %)Was my first thought, too, but doesn't make a difference if you shorten the String to "ABCDE" - same issue.
That really messes things up.
Just define the stringfield as a field of 20 characters and the code should work fine.
// bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,0,CP_UTF8); bd.FieldDefs.Add('Str5Field', ftString, 20);
Just try it.
bd.FieldDefs.Add('Str5Field', ftString, 20);
The problem could also be in the precision of -1 or something else.
Using the simple Add() version works for me.
Yes, i wondered about that, too (since when do you need precision for Strings?!?!), but i think OP used this overloaded function because of the following params after precision (required, readonly, codepage)I think the fieldNo of 0 is the problem.
Yes, i wondered about that, too (since when do you need precision for Strings?!?!), but i think OP used this overloaded function because of the following params after precision (required, readonly, codepage)I think the fieldNo of 0 is the problem.
Make it one (1) and it works.
// bd.FieldDefs.Add('Str5Field', ftString, 20); bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,1,CP_UTF8);
// the fielddef will register itself here as an owned component.So don't use field 0 but start on 1 !!!!
// fieldno is 1 based !
Yep, that's it.
// bd.FieldDefs.Add('Str5Field', ftString, 20); bd.FieldDefs.Add('Str5Field',ftString,5,-1,False,False,1,CP_UTF8);
Yep. From the source:Quote// the fielddef will register itself here as an owned component.So don't use field 0 but start on 1 !!!!
// fieldno is 1 based !
Not sure if there is any documentation for this :P
RecCount=0Still doesn't explain the BOF/EOF confusion
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
ResultWhat confusion?QuoteRecCount=0Still doesn't explain the BOF/EOF confusion
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
Not sure if there is any documentation for this :Phttps://www.freepascal.org/docs-html/fcl/db/tfield.fieldno.html ("It is a 1-based index")
Ok, I came in from another end: https://www.freepascal.org/docs-html/fcl/db/tfielddef.fieldno.htmlNot sure if there is any documentation for this :Phttps://www.freepascal.org/docs-html/fcl/db/tfield.fieldno.html ("It is a 1-based index")
For a RecordCount = 1 i would expect BOF and EOF to be True.ResultWhat confusion?QuoteRecCount=0Still doesn't explain the BOF/EOF confusion
RecCount=1
BOF=FALSE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
BOF=FALSE - EOF=TRUE
recNo=1 - s=ABCDEFG
BOF=TRUE - EOF=FALSE
recNo=1 - s=ABCDEFG
They are correct in this example. (or am I missing something?)
BOF and EOF are not set until they are actually encountered.
With a POST they are not set. Only with Last, First, Next and Prior (and only in the direction you where going).
For a RecordCount = 1 i would expect BOF and EOF to be True.No. BOF and EOF are only set on movement of the cursor.
1. The cursor is on the last record, and the TDataset.Next method is called.https://www.freepascal.org/docs-html/fcl/db/tdataset.eof.html
In all other cases, EOF is False. Note: when the cursor is on the last-but-one record, and Next is called (moving the cursor to the last record), EOF will not yet be True.So, EOF will only trigger if you are trying to go past the last record. Not when you reach that last record.
Ok, I came in from another end: https://www.freepascal.org/docs-html/fcl/db/tfielddef.fieldno.htmlI agree that it is "poorly documented". I just know this because I once was involved in a bug fix related to ZEOS components which changed their RecNo to begin at 0, and this caused some trouble (https://sourceforge.net/p/zeoslib/tickets/539/).
For a RecordCount = 1 i would expect BOF and EOF to be True.No. BOF and EOF are only set on movement of the cursor.Quote1. The cursor is on the last record, and the TDataset.Next method is called.https://www.freepascal.org/docs-html/fcl/db/tdataset.eof.html
So, although you are on the last record after Append with one record, Next isn't called, so EOF is false.
Although the documentation page of BOF (https://www.freepascal.org/docs-html/fcl/db/tdataset.bof.html) isn't that clear, the same as for EOF goes for BOF.
Only exception is when there is an empty dataset. Then both BOF and EOF are true.
Also note:QuoteIn all other cases, EOF is False. Note: when the cursor is on the last-but-one record, and Next is called (moving the cursor to the last record), EOF will not yet be True.So, EOF will only trigger if you are trying to go past the last record. Not when you reach that last record.
(That's why you do a while EOF loop with Next on the end, otherwise this would go wrong)
BOF/EOF will only be set to True if you try to MOVE BEYOND the First/Last recordAh, yes !!. That was the conclusion from the conversation I remembered as well. Thx for the refresh guys/galls !
An old example from 2016 written by me and already on this forum:No, it was the FieldNo in the (overloaded) Add-Function. OP (and myself) missed that FieldNo is 1-based. OP used for that sample FieldNo=0
{$apptype console}{$mode objfpc} uses db,BufDataset; var BufDb:TBufDataset; begin BufDb:=TBufDataset.Create(nil); try BufDb.FieldDefs.Add('NAME',ftString,20); BufDb.FieldDefs.Add('NUM',ftinteger); BufDb.FieldDefs.Add('NUM2',ftInteger); BufDb.CreateDataSet; BufDb.Open; BufDb.Append; BufDb.FieldByName('NAME').Value:='Free'; BufDb.Post; BufDb.Append; BufDb.FieldByName('NAME').Value:='Pascal'; BufDb.Post; BufDb.SaveToFile('BufDb.txt'); finally BufDb.Close; BufDb.Free; end; // now, open.. BufDb := TBufDataset.Create(nil); try BufDb.LoadFromFile('BufDb.txt'); BufDb.Open; BufDb.First; Writeln(BufDb.FieldByName('NAME').Value); finally BufDb.Close; BufDb.Free; end; end.
It seems to me that just the call to open is the culprit.
https://forum.lazarus.freepascal.org/index.php/topic,33508.msg217317.html#msg217317