Subject Re: [IBO] cascade relations
Author Helen Borrie
Stan,

At 04:34 PM 24/08/2003 +0000, you wrote:
> >
> > * Make sure an ID is generated for newly inserted Classes and
> > Class_Dances records. Use GeneratorLinks for both queries (I've
> > explained how in an earlier post).
> > Also make sure you have "before insert" triggers for both tables
> > (and probably Dances too) that look like this:
> >
> > begin
> > if ( New.Blah_ID is null )
> > then New.Blah_ID = gen_id( Blah_Generator, 1 );
> > end
> >
> > ...so the ID that IBO had generated, and inserted, will not be
> > overwritten!
> >
>
>Paul,
>If you use GeneratorLinks for your query, why do you need the before
>insert trigger?

Consider the Before Insert trigger as enforcing the business rule,
regardless of the client application that accesses it. Thus, as long as
you make your trigger fire the generator ONLY if the new.PrimaryKey comes
through as null, the rule works in any conditions. You use server-based
rules to serve the database, not a single application. If the server-based
rules are broken by an application, then they are wrong rules.

GeneratorLinks (like everything else in drivers and DA components) is an
interface feature. The basic aim of the interface is to surface the API
(the function calls in the client library) as classes that your programming
language can use. All of the available Delphi components (even DBX, after
a fashion!) do that. The "extras" surface db features that exploit aspects
of engine behaviour. GeneratorLinks is such a one - it takes advantage of
the fact that generator values are totally atomic and cannot be
double-dipped or reversed. It relies on your having expressed the business
rule (your "auto-increment trigger") in the recommended,
application-independent manner.

>How can the id be overwritten when it is only being
>assigned by the GeneratorLinks in your query? Thanks.

If your trigger simply does

new.PrimaryKey = Gen_ID(TheGenerator, 1)

then it gets fired every time an insert is posted for that table,
regardless of whether the new row comes through with new.PrimaryKey null or
already assigned. So, even though you already have the PK value you want
(the one you got via GeneratorLinks), your trigger forces it to take a new
value.

In the (very common) case where the application used GeneratorLinks because
it needed to know what the new PK would be *before* the row was posted --
typically to populate the FK of the detail rows in a master-detail
structure -- your trigger breaks the relationship.

Helen