Subject | Re: [firebird-support] Re: Key violation on Primary/Unique key constraint INTEG_55/30 on table(s) |
---|---|
Author | Gaurav Sood |
Post date | 2006-03-14T02:43:35Z |
Thanks Adam,
With the INTEG_55 Key violation, what would the problem be as there is
no similar code? Let me explain. The INTEG_55 applies to the primary
key of the SampleWords table.
There is a phonetic transcript for an orthographic (normal) transcript
of speech.
On making a new phonetic transcript, we can see the transcript in a
form with a TStringGrid. On closing this 'new' transcript, the
FormClose routine for the transcript, adds untranslated words to the
database with their default phonetic translations.
This is where things go wrong. The debugger enters the below code,
jumps to the end of the first 'if' statement, then returns and enters
the code for the if statement. The code evaluates till the ExecSQL;
and Close; at which point the debugger jumps to the end of the
OnClose.
an example of a transcript with one utterance is :
my name is gaurav /// this has one RowCount & utteranceWord.count = 4
with UtterancesStringGrid, NewSampleWordQuery do
for idx := 0 to RowCount - 1 do
begin
{ Add untranslated utterances to SampleWords with default
dictionary translation. }
if TTranslationState(Objects[0, idx]) = tsUnTranslated then
begin
TokeniseUtterance(Cells[0, idx], TStrings(utteranceWords));
{ Utterance IDX. }
Params[1].AsSmallInt
:= UtteranceIDQuery.Fields[0].AsInteger;
{ Insert each word in utterance into SampleWords. }
for jdx := 0 to utteranceWords.Count - 1 do
begin
{ UtteranceWordIDX. }
Params[5].AsSmallInt := jdx + 1;
{ Orthographic. }
Params[2].AsString := utteranceWords[jdx];
{ Target. }
Params[3].AsString
:= Dictionary.FindFirst(utteranceWords[jdx]);
{ Result. }
Params[4].AsString := Params[3].AsString;
ExecSQL;
Close;
end;
end;
UtteranceIDQuery.Next;
TranscriptProgressDialog.Gauge.Progress := idx;
end;
utteranceWords.Free;
UtteranceIDQuery.EnableControls;
RestoreCursor;
TranscriptProgressDialog.Close;
end;
I believe the query they are calling is:
select U.IDX from Utterances U, Transcriptions T
where T.ID = :TranscriptionID
and U.SampleID = T.SampleID
and U.Speaker = T.Speaker
order by U.IDX
Thanks again,
Gaurav
end;On 3/14/06, Adam <s3057043@...> wrote:
Analyst
B. Engineering, B. IT
A.N.U (2004)
M: +61 401 409 620
H: +61 3 9376 8580
"In life, always do right. This will gratify some people and astonish the rest."
— Mark Twain
With the INTEG_55 Key violation, what would the problem be as there is
no similar code? Let me explain. The INTEG_55 applies to the primary
key of the SampleWords table.
There is a phonetic transcript for an orthographic (normal) transcript
of speech.
On making a new phonetic transcript, we can see the transcript in a
form with a TStringGrid. On closing this 'new' transcript, the
FormClose routine for the transcript, adds untranslated words to the
database with their default phonetic translations.
This is where things go wrong. The debugger enters the below code,
jumps to the end of the first 'if' statement, then returns and enters
the code for the if statement. The code evaluates till the ExecSQL;
and Close; at which point the debugger jumps to the end of the
OnClose.
an example of a transcript with one utterance is :
my name is gaurav /// this has one RowCount & utteranceWord.count = 4
with UtterancesStringGrid, NewSampleWordQuery do
for idx := 0 to RowCount - 1 do
begin
{ Add untranslated utterances to SampleWords with default
dictionary translation. }
if TTranslationState(Objects[0, idx]) = tsUnTranslated then
begin
TokeniseUtterance(Cells[0, idx], TStrings(utteranceWords));
{ Utterance IDX. }
Params[1].AsSmallInt
:= UtteranceIDQuery.Fields[0].AsInteger;
{ Insert each word in utterance into SampleWords. }
for jdx := 0 to utteranceWords.Count - 1 do
begin
{ UtteranceWordIDX. }
Params[5].AsSmallInt := jdx + 1;
{ Orthographic. }
Params[2].AsString := utteranceWords[jdx];
{ Target. }
Params[3].AsString
:= Dictionary.FindFirst(utteranceWords[jdx]);
{ Result. }
Params[4].AsString := Params[3].AsString;
ExecSQL;
Close;
end;
end;
UtteranceIDQuery.Next;
TranscriptProgressDialog.Gauge.Progress := idx;
end;
utteranceWords.Free;
UtteranceIDQuery.EnableControls;
RestoreCursor;
TranscriptProgressDialog.Close;
end;
I believe the query they are calling is:
select U.IDX from Utterances U, Transcriptions T
where T.ID = :TranscriptionID
and U.SampleID = T.SampleID
and U.Speaker = T.Speaker
order by U.IDX
Thanks again,
Gaurav
end;On 3/14/06, Adam <s3057043@...> wrote:
> --- In firebird-support@yahoogroups.com, "Gaurav Sood"--
> <sood.gaurav@...> wrote:
> >
> > Hi Helen
> >
> > I've run through the program with the debugger and found that once we
> > try to make a new person with the GUI, it calls the Person.pas file
> > OnShow routine
> >
> > procedure TPersonDlg.FormShow(Sender: TObject);
> > var
> > personType: TPersonTypeEnum;
> >
> > begin
> >
> > { Check for new Person. }
> > if Person < 1 then
> > begin
> > *** Person := NewPerson;
> > Status := pdNew;
> > end
> > else
> > Status := pdEdit;
> >
> >
> > The *** Person := NewPerson; is an internal private function that does
> > the below:
> >
> > function TPersonDlg.NewPerson: TPersonID;
> > begin
> > with ApplicationForm.ScratchQuery do
> > begin
> > { Create a new record in People. }
> > Close;
> > SQL.Clear;
> > *** SQL.Add('Insert into People (ID) values (0)');
> > ExecSQL;
> >
> > { Get ID for new Person. }
> > Close;
> > SQL.Clear;
> > SQL.Add('Select max(ID) from People');
>
> This is a really dumb way of assigning a new ID.
>
> 1) It is slow unless you have a descending index on the PK field
>
> but more importantly
>
> 2) It does NOT work in a multi-transaction environment. Each
> transaction has an isolated view of the database. If I called this
> silly procedure and it gave me ID 100, which I then inserted but have
> not yet committed, then you call the procedure, you will also be given
> ID 100 to use, and you will get the error you received before.
>
> In Firebird, use generators to assign numbers that are guaranteed to
> be unique.
>
> Some initial SQL to create and initialise the generator
>
> CREATE GENERATOR GEN_PEOPLEID;
> SET GENERATOR GEN_PEOPLEID TO 100;
> (change 100 to the maximum value currently allocated)
>
> And change the query to:
>
> SQL.Add('Select gen_id(GEN_PEOPLEID,1) from RDB$DATABASE');
>
> This will then ALWAYS give you a unique number for your person ID.
>
> Adam
>
>
>
>
>
>
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Visit http://firebird.sourceforge.net and click the Resources item
> on the main (top) menu. Try Knowledgebase and FAQ links !
>
> Also search the knowledgebases at http://www.ibphoenix.com
>
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>
> Yahoo! Groups Links
>
>
>
>
>
>
>
Analyst
B. Engineering, B. IT
A.N.U (2004)
M: +61 401 409 620
H: +61 3 9376 8580
"In life, always do right. This will gratify some people and astonish the rest."
— Mark Twain