× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



On 12-Apr-2012 14:34 , Thomas Garvey wrote:
CRPence on Wednesday, April 11, 2012 5:22 PM wrote:

<<SNIP>> If a SEQUENCE could possibly be used instead, <<SNIP>>

On 11-Apr-2012 09:47 , Thomas Garvey wrote:

I'm using embedded SQL to update a counter in a database field,
but would also like to know the new value of that counter without
having to retrieve the newly updated record.

For example, using embedded SQL in my RPGLE, as follows...

exec sql
update fileX
set counter = counter + 1
where keyfield = :something

Since the "counter" value in the original example [snippet inserted above] seemed to be tied to a particular key value, I figured that using a SEQUENCE would probably be impractical :-(

I do not recall a release level ever being mentioned.?

I can't use the SEQUENCE or IDENTITY phrase. My understanding is
that their scope is table wide, and my intention is subsidiary to
other fields.

The IDENTITY is. The SEQUENCE however, is separate from a TABLE, so the application(s) decide for what and how the sequence is utilized.

MY use would be similar to a count of how many times a record has
been changed. So, the counter is not a key value or a sequence that
is unique across the table.

The SEQUENCE could be used, even in the described scenario, although probably not very succinctly. Establishing a SEQUENCE for each effective 'group' of data, for example, would be an undesirable implementation due to the potentially large number of sequence objects to maintain.

Presumably the keyfield is uniquely keyed such that just one counter value is tracked to each key value.? And is the limit also specific to each key value? If so, then the limit would seem best stored in the same row, in another column. A CHECK CONSTRAINT could then enforce the maximum in that case; e.g. alter table fileX add constraint fileX_ck_counter check (counter < max_counter). This is easiest, if possible; other applications could even remain unchanged, referring to a LF without the new column.

Especially if the previous comments seem silly... Perhaps offering a more explicit example(s) than the very generically described example originally given, to include DDL with constraints and\or unique indexes and sample data, would assist to better describe the data and scenario.?

I'd like to be able to execute the SQL UPDATE, incrementing the
counter field (multiple programs will be able to update this
counter),

Where are the limits defined\stored; a limits_test() function, a limits database file, other...? Obviously the program that would be doing the UPDATE knows the limits, because that program is supposed to know to respond if the limit is reached.

Consider that the following statement variations for which "row not found" is the result, the counter is known to have previously grown to its limit [if the key value can be assumed to exist; e.g. in the second statement that would be ensured when the limits_file is also a parent file off fileX in a referential constraint]:

update fileX set counter=counter+1
where keyfield=:something
and counter<limits_test(:something)

update fileX set counter=counter+1
where keyfield=:something
and counter<(select counter_limit from limits_file
where keyfield=:something)

As a variation of the above... two separate updates could detect both the will-become-maximum and the at-maximum, performing just one update however in all but the /boundary/ cases. Using the UDF model from above, in pseudo-code:

execsql
update fileX set counter=counter+1
where keyfield=:something
and counter<limits_test(:something)-1 -- two down from max
; -- if row-found and updated, increment done within bounds
if row-not-found then do // already one down from, or at max
notify(verging-on-max);
execsql
update fileX set counter=counter+1
where keyfield=:something
and counter<limits_test(:something)
; -- if row-found and updated, then increment was to maximum
if row-not-found then do // already at max, do not increment
notify(at-max);
end;
end;


and when the counter has reached a variable limit, subsequent logic
would send a message to a user that the limit has been reached.

Presumably a hard-stop on any other requests since having hit the limit? That is, if the user who was notified of the condition has not effected some resolution nor any other automation having effected resolution, than surely any other increment should fail.?

FWiW:

While the standalone UPDATE is nice to just let the DB do the work atomically, the row data is still paged [or faulted] into memory. If the reason for not wanting "to retrieve the newly updated record" is mostly about performance, actual testing may prove concerns to be unfounded or at least subdued.

There would be other /tricks/ to get the column value from elsewhere, for example via a TRIGGER or the journal receiver, but obtaining the value from the row itself is most obvious [for the code]. With IBM i 7.1 the SQL Global Variables may enable a more integrated means; i.e. less of a "trick".

Consider encapsulating the work in an atomic SQL or External stored PROCEDURE, or if already running with isolation perhaps make the work part of an overall transaction that is later committed after both the increment activity and the remaining work in that transaction is deemed complete:

declare cursor as select for update of counter
open
fetch
if below-limit then update set increment where current of
if limit-reached by increment then optionally:
feedback\signal sqlstate to inform of at-maximum
set an output variable with the new counter

the program, instead of the SQL UPDATE uses SQL CALL:
call theProc(:something, :rtn_counter)
if so_informed then this program notifies user of limit-reached; either by returned counter value or failure

As a procedure instead of inline to the program, all programs [including external client requester] that update the field could use the same interface. However....

Having suggested that "multiple programs will be able to update this counter" I wonder if that might intend to imply that all interfaces for which an update might be requested should enforce that notification of the verging-on-max condition, as a "business rule".? If so, then perhaps the work might best be pushed down to a TRIGGER; if there could not be an assurance that all programs would be coded to use a common ROUTINE to effect the update\increment.?

Regards, Chuck

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.