Subject Re: Key violation on Primary/Unique key constraint INTEG_55/30 on table(s)
Author Adam
--- In firebird-support@yahoogroups.com, "Gaurav Sood"
<sood.gaurav@...> wrote:
>
> 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
>

I don't believe you. For a start this is a select statement, so
unless you have a stored procedure involved you will not get a
constraint error on a select (selects do not insert any data).

The second reason I don't believe you is because you are clearly
assigning 5 parameters, and you are not getting an exception saying
something along the lines 'What is params[5]?? I only know Params[0]'

Do a showmessage or check it in the debugger to get the REAL query.

Note down all queries it is running. It will either be blindingly
obvious (like the same query values twice), or it will give you a
good heads up as to which tables/stored procedures are being
impacted. Then investigate the triggers on those tables (and cascade,
you will need to check triggers on tables modified in your triggers).

From here down is me venting, ignore if you wish:

with ... do is really dumb. I mean it is a great shortcut, until you
have to maintain the code. I have spent countless hours tracking bugs
because someone thought they would save 5 minutes. When you nest them
it gets even worse, because you may not be using the object you think
you are. Things like Next and Close are procedures in various classes.

It may take 5 seconds longer to copy the object name using shift-ctrl
select but you are less likely to encounter a problem looking at the
wrong query. Also dont forget ctrl+space for autocomplete.

Apart from being more readable and more obvious when you have a bug,
there is another added benefit in that the debugger is more likely to
give you the correct hint message.


Adam