Subject | Strange behavior in TIBOTable |
---|---|
Author | Joe Martinez |
Post date | 2003-02-02T08:47:03Z |
A customer of my has observed a strange behavior, and I have reproduced it.
I have a TIBOTable. It's key field (CUSTID) is, of course, a required
field. I perform the following series of events:
1) I start my app. My customer table is automatically opened, and I'm
automatically on the first customer record (CUSTID of 1). The CUSTID is
displayed on my form, so I know that it's set (not null).
2) I Edit the record (click on the Edit button on the TDBNavigator).
3) I change something in the record, and click on the check mark in the
TDBNavigator.
4) I get an exception: CUSTID is a required field.
If I then click on the X on the TDBNavigator, and then repeat steps 2-3, it
works fine and doesn't give me the exception.
Also, this only happens if this is the first thing that I do after starting
the app, and only if it's the first record in the table. If I scroll to
another record and come back to it, I don't have the problem.
Using the debugger, I traced it to the following procedure:
procedure TIB_Dataset.CheckRequiredFields;
var
ii: Integer;
begin
for ii := 0 to Fields.ColumnCount - 1 do
with Fields[ii] do
if IsNull and not ReadOnly and not Computed and Required then
begin
FocusControl;
raise EIB_DatasetError.Create(Format(E_Required_Field,[DisplayName]));
end;
end;
The exception is being raised in the third to last line. So, apparently,
the system thinks that the CUSTID field is null, even though there's no way
that it could be. All I'm doing is editing an existing record. The
existing record already has a non-null value for CUSTID, and I'm definitely
not resetting it to null. It just seems strange that it only happens in
the very limited set of circumstances (which I've already explained).
Here's the DML for my TIBOTable:
object CustTable: TIBOTable
DatabaseName = 'SMRDBS_MAN'
FetchWholeRows = False
KeyLinks.Strings = (
'CUSTID')
RecordCountAccurate = True
BeforeDelete = CustTableBeforeDelete
BeforePost = CustTableBeforePost
OnNewRecord = CustTableNewRecord
OnPostError = CustTablePostError
TableName = 'CUSTOMER'
FieldOptions = []
Left = 593
Top = 228
object CustTableCUSTID: TIntegerField
FieldName = 'CUSTID'
Required = True
end
object CustTableCUSTFNAME: TStringField
FieldName = 'CUSTFNAME'
Size = 25
end
object CustTableCUSTLNAME: TStringField
FieldName = 'CUSTLNAME'
Size = 25
end
object CustTableCUSTADDRESS: TStringField
FieldName = 'CUSTADDRESS'
Size = 80
end
object CustTableCUSTCITY: TStringField
FieldName = 'CUSTCITY'
end
object CustTableCUSTSTATE: TStringField
FieldName = 'CUSTSTATE'
Size = 2
end
object CustTableCUSTZIP: TStringField
FieldName = 'CUSTZIP'
Size = 10
end
object CustTableCUSTTYPE: TStringField
FieldName = 'CUSTTYPE'
Size = 10
end
object CustTableCUSTPHONE1: TStringField
FieldName = 'CUSTPHONE1'
end
object CustTableCUSTPHONE2: TStringField
FieldName = 'CUSTPHONE2'
end
object CustTableCUSTINTCLASS: TStringField
FieldName = 'CUSTINTCLASS'
Size = 1
end
object CustTableCUSTSPARE1: TStringField
FieldName = 'CUSTSPARE1'
Size = 50
end
object CustTableCUSTSPARE2: TStringField
FieldName = 'CUSTSPARE2'
Size = 50
end
object CustTableCUSTDATE1: TDateTimeField
FieldName = 'CUSTDATE1'
OnSetText = CustTableCUSTDATE1SetText
end
object CustTableCUSTDATE2: TDateTimeField
FieldName = 'CUSTDATE2'
OnSetText = CustTableCUSTDATE2SetText
end
object CustTableCUSTEMAIL: TStringField
FieldName = 'CUSTEMAIL'
Size = 80
end
object CustTableSTOREID: TIntegerField
FieldName = 'STOREID'
Required = True
end
object CustTableCUSTDISCOUNT: TIBOFloatField
FieldName = 'CUSTDISCOUNT'
end
object CustTableCUSTTAXEXEMPT: TStringField
FieldName = 'CUSTTAXEXEMPT'
Size = 1
end
object CustTableCUSTINACTIVE: TStringField
FieldName = 'CUSTINACTIVE'
Size = 1
end
object CustTableCUSTNOTES: TMemoField
FieldName = 'CUSTNOTES'
BlobType = ftMemo
Size = 2000
end
object CustTableCUSTBDAY: TDateTimeField
FieldName = 'CUSTBDAY'
OnSetText = CustTableCUSTBDAYSetText
end
object CustTableCUSTPHONEUNF: TStringField
FieldName = 'CUSTPHONEUNF'
end
object CustTableCUSTBADCHECK: TStringField
FieldName = 'CUSTBADCHECK'
Size = 1
end
object CustTableCUSTTERMS: TStringField
FieldName = 'CUSTTERMS'
end
object CustTableCUSTCREDITLIMIT: TFloatField
FieldName = 'CUSTCREDITLIMIT'
end
object CustTableCUSTTOTALMONEY: TFloatField
FieldName = 'CUSTTOTALMONEY'
end
object CustTableCUSTTOTALVOLUME: TFloatField
FieldName = 'CUSTTOTALVOLUME'
end
end
Any ideas???
-Joe
I have a TIBOTable. It's key field (CUSTID) is, of course, a required
field. I perform the following series of events:
1) I start my app. My customer table is automatically opened, and I'm
automatically on the first customer record (CUSTID of 1). The CUSTID is
displayed on my form, so I know that it's set (not null).
2) I Edit the record (click on the Edit button on the TDBNavigator).
3) I change something in the record, and click on the check mark in the
TDBNavigator.
4) I get an exception: CUSTID is a required field.
If I then click on the X on the TDBNavigator, and then repeat steps 2-3, it
works fine and doesn't give me the exception.
Also, this only happens if this is the first thing that I do after starting
the app, and only if it's the first record in the table. If I scroll to
another record and come back to it, I don't have the problem.
Using the debugger, I traced it to the following procedure:
procedure TIB_Dataset.CheckRequiredFields;
var
ii: Integer;
begin
for ii := 0 to Fields.ColumnCount - 1 do
with Fields[ii] do
if IsNull and not ReadOnly and not Computed and Required then
begin
FocusControl;
raise EIB_DatasetError.Create(Format(E_Required_Field,[DisplayName]));
end;
end;
The exception is being raised in the third to last line. So, apparently,
the system thinks that the CUSTID field is null, even though there's no way
that it could be. All I'm doing is editing an existing record. The
existing record already has a non-null value for CUSTID, and I'm definitely
not resetting it to null. It just seems strange that it only happens in
the very limited set of circumstances (which I've already explained).
Here's the DML for my TIBOTable:
object CustTable: TIBOTable
DatabaseName = 'SMRDBS_MAN'
FetchWholeRows = False
KeyLinks.Strings = (
'CUSTID')
RecordCountAccurate = True
BeforeDelete = CustTableBeforeDelete
BeforePost = CustTableBeforePost
OnNewRecord = CustTableNewRecord
OnPostError = CustTablePostError
TableName = 'CUSTOMER'
FieldOptions = []
Left = 593
Top = 228
object CustTableCUSTID: TIntegerField
FieldName = 'CUSTID'
Required = True
end
object CustTableCUSTFNAME: TStringField
FieldName = 'CUSTFNAME'
Size = 25
end
object CustTableCUSTLNAME: TStringField
FieldName = 'CUSTLNAME'
Size = 25
end
object CustTableCUSTADDRESS: TStringField
FieldName = 'CUSTADDRESS'
Size = 80
end
object CustTableCUSTCITY: TStringField
FieldName = 'CUSTCITY'
end
object CustTableCUSTSTATE: TStringField
FieldName = 'CUSTSTATE'
Size = 2
end
object CustTableCUSTZIP: TStringField
FieldName = 'CUSTZIP'
Size = 10
end
object CustTableCUSTTYPE: TStringField
FieldName = 'CUSTTYPE'
Size = 10
end
object CustTableCUSTPHONE1: TStringField
FieldName = 'CUSTPHONE1'
end
object CustTableCUSTPHONE2: TStringField
FieldName = 'CUSTPHONE2'
end
object CustTableCUSTINTCLASS: TStringField
FieldName = 'CUSTINTCLASS'
Size = 1
end
object CustTableCUSTSPARE1: TStringField
FieldName = 'CUSTSPARE1'
Size = 50
end
object CustTableCUSTSPARE2: TStringField
FieldName = 'CUSTSPARE2'
Size = 50
end
object CustTableCUSTDATE1: TDateTimeField
FieldName = 'CUSTDATE1'
OnSetText = CustTableCUSTDATE1SetText
end
object CustTableCUSTDATE2: TDateTimeField
FieldName = 'CUSTDATE2'
OnSetText = CustTableCUSTDATE2SetText
end
object CustTableCUSTEMAIL: TStringField
FieldName = 'CUSTEMAIL'
Size = 80
end
object CustTableSTOREID: TIntegerField
FieldName = 'STOREID'
Required = True
end
object CustTableCUSTDISCOUNT: TIBOFloatField
FieldName = 'CUSTDISCOUNT'
end
object CustTableCUSTTAXEXEMPT: TStringField
FieldName = 'CUSTTAXEXEMPT'
Size = 1
end
object CustTableCUSTINACTIVE: TStringField
FieldName = 'CUSTINACTIVE'
Size = 1
end
object CustTableCUSTNOTES: TMemoField
FieldName = 'CUSTNOTES'
BlobType = ftMemo
Size = 2000
end
object CustTableCUSTBDAY: TDateTimeField
FieldName = 'CUSTBDAY'
OnSetText = CustTableCUSTBDAYSetText
end
object CustTableCUSTPHONEUNF: TStringField
FieldName = 'CUSTPHONEUNF'
end
object CustTableCUSTBADCHECK: TStringField
FieldName = 'CUSTBADCHECK'
Size = 1
end
object CustTableCUSTTERMS: TStringField
FieldName = 'CUSTTERMS'
end
object CustTableCUSTCREDITLIMIT: TFloatField
FieldName = 'CUSTCREDITLIMIT'
end
object CustTableCUSTTOTALMONEY: TFloatField
FieldName = 'CUSTTOTALMONEY'
end
object CustTableCUSTTOTALVOLUME: TFloatField
FieldName = 'CUSTTOTALVOLUME'
end
end
Any ideas???
-Joe