Subject | RE: [firebird-support] Upd8 SQL Conundrum |
---|---|
Author | Helen Borrie |
Post date | 2005-08-27T00:36:57Z |
At 11:05 AM 26/08/2005 -0500, you wrote:
being in correct date/time order. With this proviso, we are not concerned
about which client_id is involved. Every generator value is unique, so the
ordering for each client's group will be correct if the order of the
incoming set is correct.
When real-time use kicks in, it will be dependent on notes being entered in
chronologically-correct order (which might or might not be the case.)
If you need each CLIENT_ID to have its own, independent "package" of
sequence numbers, i.e. "1" for the first visit..."10" for the 10th, etc.,
see Svein Erling's reply for a way to fix the existing data, *provided*
(again) you are certain that the records arriving in the Firebird table are
in strict date order. It will be safer if ENTRY_DATE has been maintained
as a timestamp (which isn't likely if the source data came from Access):
UPDATE NOTES N1
SET ADMIT_ORDINAL = SELECT COUNT(*) FROM NOTES N2
WHERE N2.CLIENT_ID = N1.CLIENT_ID
AND N2.ENTRY_DATE <= N1.ENTRY_DATE
Do this as the only user connected and *only* if you are certain about the
date order of the data. Otherwise, write a SP to do it. (Myself, I would
do it with a SP, regardless of what I thought I knew about the arrival
order of the data. The SP would loop through a set ordered by CLIENT_ID,
ENTRY_DATE and apply an incrementing counter variable to each row's
ADMIT_ORDINAL, resetting the counter variable when the CLIENT_ID changes.)
After data loading, life gets more complicated if it's essential to
maintain these sequences per CLIENT_ID, rather than using the generator to
record the order in which notes entered the system.
Once you have the data fixed, you would need to place a unique constraint
on (CLIENT_ID, ADMIT_ORDINAL).
Then write a Before Insert trigger to calculate the new value. Include a
handler for the constraint violation to deal with cases where notes are
being entered out of sequence and/or by different users/transactions at the
same time.
If these conditions are likely to occur regularly - new NOTES records being
added outside real time - then this approach is too simplistic to be
reliable: you would still need the ENTRY_DATE (a TIMESTAMP, not a DATE) in
the picture to determine the sequence reliably. If these are clinical
notes we are talking about here, the date is crucial in both the clinical
and legal respects; and if multiple consultations occurred on the same day
it is possible for the progression sequence of the notes to be a matter of
life and death.
But, then, if it's been OK to store the data in Access in the past, it's
probably not a life-and-death thing. BoTox clinic? Poodle pedicures?
./heLen
><< create generator gen_admit_ordinal;Yes. At data-migration time, it will be dependent on the arriving data
>
>then ----
>
>create trigger bi_patient_admissions
>active before insert
>as
>begin
> if (new.admit_ordinal is null) then
> new.admit_ordinal = gen_id(gen_admit_ordinal,1);
>end>>
>
>Won't this just increment the Admit_Ordinal lineally, regardless of
>Client_ID?
being in correct date/time order. With this proviso, we are not concerned
about which client_id is involved. Every generator value is unique, so the
ordering for each client's group will be correct if the order of the
incoming set is correct.
When real-time use kicks in, it will be dependent on notes being entered in
chronologically-correct order (which might or might not be the case.)
If you need each CLIENT_ID to have its own, independent "package" of
sequence numbers, i.e. "1" for the first visit..."10" for the 10th, etc.,
see Svein Erling's reply for a way to fix the existing data, *provided*
(again) you are certain that the records arriving in the Firebird table are
in strict date order. It will be safer if ENTRY_DATE has been maintained
as a timestamp (which isn't likely if the source data came from Access):
UPDATE NOTES N1
SET ADMIT_ORDINAL = SELECT COUNT(*) FROM NOTES N2
WHERE N2.CLIENT_ID = N1.CLIENT_ID
AND N2.ENTRY_DATE <= N1.ENTRY_DATE
Do this as the only user connected and *only* if you are certain about the
date order of the data. Otherwise, write a SP to do it. (Myself, I would
do it with a SP, regardless of what I thought I knew about the arrival
order of the data. The SP would loop through a set ordered by CLIENT_ID,
ENTRY_DATE and apply an incrementing counter variable to each row's
ADMIT_ORDINAL, resetting the counter variable when the CLIENT_ID changes.)
After data loading, life gets more complicated if it's essential to
maintain these sequences per CLIENT_ID, rather than using the generator to
record the order in which notes entered the system.
Once you have the data fixed, you would need to place a unique constraint
on (CLIENT_ID, ADMIT_ORDINAL).
Then write a Before Insert trigger to calculate the new value. Include a
handler for the constraint violation to deal with cases where notes are
being entered out of sequence and/or by different users/transactions at the
same time.
If these conditions are likely to occur regularly - new NOTES records being
added outside real time - then this approach is too simplistic to be
reliable: you would still need the ENTRY_DATE (a TIMESTAMP, not a DATE) in
the picture to determine the sequence reliably. If these are clinical
notes we are talking about here, the date is crucial in both the clinical
and legal respects; and if multiple consultations occurred on the same day
it is possible for the progression sequence of the notes to be a matter of
life and death.
But, then, if it's been OK to store the data in Access in the past, it's
probably not a life-and-death thing. BoTox clinic? Poodle pedicures?
./heLen