CREATE-TRIGGER, LIST-TRIGGER, DELETE-TRIGGER
I do see the LIST.SICA command, which lists universe triggers on SQL files....do we not have triggers on regular PICK files in universe?
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
CREATE-TRIGGER, LIST-TRIGGER, DELETE-TRIGGER
I do see the LIST.SICA command, which lists universe triggers on SQL files....do we not have triggers on regular PICK files in universe?
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
In Universe, it's actually two words - CREATE TRIGGER.
Try HELP SQL CREATE for more info.
Brian
CREATE-TRIGGER, LIST-TRIGGER, DELETE-TRIGGER
I do see the LIST.SICA command, which lists universe triggers on SQL files....do we not have triggers on regular PICK files in universe?
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
Yes on UV, triggers are documented/part of SQL engine.
look at HELP SQL CREATE TRIGGER / DROP TRIGGER.
You can use it against standard non SQL uv datafile.
be carefull, if you change the subr after create trigger you must drop/create.
Regards
------------------------------
Manu Fernandes
------------------------------
Yes on UV, triggers are documented/part of SQL engine.
look at HELP SQL CREATE TRIGGER / DROP TRIGGER.
You can use it against standard non SQL uv datafile.
be carefull, if you change the subr after create trigger you must drop/create.
Regards
------------------------------
Manu Fernandes
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
yes, triggers are member of universe 'SQL engine'... you miss the semi-colon at then end of the phrase ...
CREATE TRIGGER TRIGGER1 AFTER INSERT OR UPDATE OR DELETE ON MYFILE FOR EACH ROW CALLING '*MYTRIGGER' ;
i'm used to create a VOC PARAGRAPH to set/update a trigger on a file
first, basic/catalog globally
BASIC BP TRIG.LOG.b
CATALOGI BP *TRIG.LOG TRIG.LOG.b FORCE
next, define the paragraph
ED VOC SET.TRIG.LOG
PA
DROP TRIGGER <<I2,filename>> TRIGLOG ;
CREATE TRIGGER TRIGLOG AFTER INSERT OR UPDATE OR DELETE ON <<I2,filename>> FOR EACH ROW CALLING '*TRIG.LOG';
next, use on file SET.TRIG.LOG MYFILE
------------------------------
Manu Fernandes
------------------------------
yes, triggers are member of universe 'SQL engine'... you miss the semi-colon at then end of the phrase ...
CREATE TRIGGER TRIGGER1 AFTER INSERT OR UPDATE OR DELETE ON MYFILE FOR EACH ROW CALLING '*MYTRIGGER' ;
i'm used to create a VOC PARAGRAPH to set/update a trigger on a file
first, basic/catalog globally
BASIC BP TRIG.LOG.b
CATALOGI BP *TRIG.LOG TRIG.LOG.b FORCE
next, define the paragraph
ED VOC SET.TRIG.LOG
PA
DROP TRIGGER <<I2,filename>> TRIGLOG ;
CREATE TRIGGER TRIGLOG AFTER INSERT OR UPDATE OR DELETE ON <<I2,filename>> FOR EACH ROW CALLING '*TRIG.LOG';
next, use on file SET.TRIG.LOG MYFILE
------------------------------
Manu Fernandes
------------------------------
DROP TRIGGER filename triggername ;------------------------------
Manu Fernandes
------------------------------
yes, triggers are member of universe 'SQL engine'... you miss the semi-colon at then end of the phrase ...
CREATE TRIGGER TRIGGER1 AFTER INSERT OR UPDATE OR DELETE ON MYFILE FOR EACH ROW CALLING '*MYTRIGGER' ;
i'm used to create a VOC PARAGRAPH to set/update a trigger on a file
first, basic/catalog globally
BASIC BP TRIG.LOG.b
CATALOGI BP *TRIG.LOG TRIG.LOG.b FORCE
next, define the paragraph
ED VOC SET.TRIG.LOG
PA
DROP TRIGGER <<I2,filename>> TRIGLOG ;
CREATE TRIGGER TRIGLOG AFTER INSERT OR UPDATE OR DELETE ON <<I2,filename>> FOR EACH ROW CALLING '*TRIG.LOG';
next, use on file SET.TRIG.LOG MYFILE
------------------------------
Manu Fernandes
------------------------------
1/ Trigger must be dropped and created again.
Problem
If trigger program is changed after creation, the trigger must be dropped and created again. This presents problems, for example, when a new release of application software is deployed. Typically, program libraries will be reloaded and recataloged. If trigger programs have changed, all files will need to be checked, triggers dropped and recreated.
Cause
The pointer to the trigger program object code resides in the SICA of the file header.
Solution
Workaround: Make the trigger program a simple call to an external subroutine. The external subroutine may now be modified without affecting the trigger
2/ triggers execution are part of an implicit 'TRANSACTION' processing
2.1/ the TRANSACTION BEGin is started by the 'WRITE' verb of the parent execution. Then all BEGIN TRANSACTION restriction occurs inside triggers.
2.2 / you must get the lock (READU / RECORDLOCKU) before update another file
2.3/ you can't execute verb which require a new level.
2.4/ be carefull if the parent already have the lock of a record, the on-file record can be wrong value
2.5/ if the parent start a explicit BEGIN TRANSACTION, all locks set by the triggers are held by the session (as part of the parent TRANSACTION) until TRANSACTION COMMIT/ROLLBACK ...
2.6/ if the parent use explicit BEGIN TRANSACTION and perform ROLLBACK triggers update are ROLLBACK'ed too, the only way to have the trace of the triggers call is via OPENSEQ/WRITESEQ which are not part of TRANSACTION processing.
3/ check trigger infinite loop
sometime, you can create infinite loop, if triggers update file where triggers are fired.
you can use the system(9001) to check if the trigger is in the parent call stack.
4/ triggers must be created on 'closed file'
if session-A have the file opened on runtime filevariable/common and session-B CREATE TRIGGER on the file, the session-A does not known the trigger, session-A must reopen the file. because, as for indices, triggers info/p-code are in the header of the file - loaded on the filevariable.
I hope this help
------------------------------
Manu Fernandes
------------------------------
CREATE-TRIGGER, LIST-TRIGGER, DELETE-TRIGGER
I do see the LIST.SICA command, which lists universe triggers on SQL files....do we not have triggers on regular PICK files in universe?
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
We use them very sparingly but I've have good success using the methods defined on this post.
https://www.intl-spectrum.com/Article/r310/Auditing_Database_Changes_with_UniVerse_Indexing_Subroutines
Harry
------------------------------
Harry Hambrick
Senior Software Developer
Rooms To Go Inc
Seffner FL US
------------------------------
We use them very sparingly but I've have good success using the methods defined on this post.
https://www.intl-spectrum.com/Article/r310/Auditing_Database_Changes_with_UniVerse_Indexing_Subroutines
Harry
------------------------------
Harry Hambrick
Senior Software Developer
Rooms To Go Inc
Seffner FL US
------------------------------
One difference that has not been mentioned in relation to triggers with UniVerse and UniData. When you use a trigger it will be treated as though it was part of a transaction. On UniData you will never have noticed this as UniData does not enforce isolation levels of a transaction, you have to code to an isolation level. In UniVerse isolation levels can be enforced and by default the UniVerse tuneable ISOMODE is set to 1, which enforces protection against UnCommitted Reads.
In short for someone coming from UniData to UniVerse and wanting to use Triggers (or transactions) then every record that you are going to update should have an exclusive lock set on it and if you are going to just read a record in a Trigger (or transaction) you should read the record with a shared lock (see READL).
Failure to follow these rules in UniVerse you may see an error stating that the locks are not set to the required level to perform an operation. As I said these rules are not enforced in UniData (but should be).
Thanks,
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
CREATE-TRIGGER, LIST-TRIGGER, DELETE-TRIGGER
I do see the LIST.SICA command, which lists universe triggers on SQL files....do we not have triggers on regular PICK files in universe?
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
At first, iirc, they were slow. I don't think that is a problem now, but the RAID debugger doesn't play nicely with them the last time I checked.
Does anyone know if that is still true? (I've always found the debugger the buggiest part of most programming languages.)
When Prime Information first introduced indexing decades ago, I was a beta site. I recognized that, with a little work, one could effect a trigger by indexing NO.NULLS, letting your subroutine do whatever you need, then always returning null. The tricky part was knowing if your subroutine were being called for an add, delete, or change. (An index gets called once for an add, 2x for a change (evaluate the old version, then the new & see if it has changed), and 1x for a delete of the record being indexed.) I suggested inventing an @-variable flag for that. Finally, at UV 11.x we have @IDX.IOTYPE so you can do that more easily.
I was going to write up how to do that, but earlier in this thread Harry Hambrick already pointed to a Spectrum by Clif Oliver: www.intl-spectrum.com/Article/r310/Auditing_Database_Changes_with_UniVerse_Indexing_Subroutines. Kudos, Clif.
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
San Ignacio BZ
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
This lives in the uv account and there may be called just catdir
------------------------------
Will Johnson
Systems Analyst
Rocket Forum Shared Account
------------------------------
One difference that has not been mentioned in relation to triggers with UniVerse and UniData. When you use a trigger it will be treated as though it was part of a transaction. On UniData you will never have noticed this as UniData does not enforce isolation levels of a transaction, you have to code to an isolation level. In UniVerse isolation levels can be enforced and by default the UniVerse tuneable ISOMODE is set to 1, which enforces protection against UnCommitted Reads.
In short for someone coming from UniData to UniVerse and wanting to use Triggers (or transactions) then every record that you are going to update should have an exclusive lock set on it and if you are going to just read a record in a Trigger (or transaction) you should read the record with a shared lock (see READL).
Failure to follow these rules in UniVerse you may see an error stating that the locks are not set to the required level to perform an operation. As I said these rules are not enforced in UniData (but should be).
Thanks,
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
This lives in the uv account and there may be called just catdir
------------------------------
Will Johnson
Systems Analyst
Rocket Forum Shared Account
------------------------------
I have been reading about the &MAP& file, and now I see the global.cat you've suggested. Are these two distinct? Or part of the same setup?
Thanks for your help!
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
One difference that has not been mentioned in relation to triggers with UniVerse and UniData. When you use a trigger it will be treated as though it was part of a transaction. On UniData you will never have noticed this as UniData does not enforce isolation levels of a transaction, you have to code to an isolation level. In UniVerse isolation levels can be enforced and by default the UniVerse tuneable ISOMODE is set to 1, which enforces protection against UnCommitted Reads.
In short for someone coming from UniData to UniVerse and wanting to use Triggers (or transactions) then every record that you are going to update should have an exclusive lock set on it and if you are going to just read a record in a Trigger (or transaction) you should read the record with a shared lock (see READL).
Failure to follow these rules in UniVerse you may see an error stating that the locks are not set to the required level to perform an operation. As I said these rules are not enforced in UniData (but should be).
Thanks,
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
We use them very sparingly but I've have good success using the methods defined on this post.
https://www.intl-spectrum.com/Article/r310/Auditing_Database_Changes_with_UniVerse_Indexing_Subroutines
Harry
------------------------------
Harry Hambrick
Senior Software Developer
Rooms To Go Inc
Seffner FL US
------------------------------
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
I have been reading about the &MAP& file, and now I see the global.cat you've suggested. Are these two distinct? Or part of the same setup?
Thanks for your help!
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
But it is not the actual catalog *code*
The code information is stored in the catdir (GLOBAL.CATDIR) file
So I suppose it matters what exactly you are looking for
Generally when I am interested in this, I'm looking for answers like Is this subroutine globally catalogued? If so, where is the actual underlying code located (for editing)? That's what I'm looking for.
------------------------------
Will Johnson
Systems Analyst
Rocket Forum Shared Account
------------------------------
At first, iirc, they were slow. I don't think that is a problem now, but the RAID debugger doesn't play nicely with them the last time I checked.
Does anyone know if that is still true? (I've always found the debugger the buggiest part of most programming languages.)
When Prime Information first introduced indexing decades ago, I was a beta site. I recognized that, with a little work, one could effect a trigger by indexing NO.NULLS, letting your subroutine do whatever you need, then always returning null. The tricky part was knowing if your subroutine were being called for an add, delete, or change. (An index gets called once for an add, 2x for a change (evaluate the old version, then the new & see if it has changed), and 1x for a delete of the record being indexed.) I suggested inventing an @-variable flag for that. Finally, at UV 11.x we have @IDX.IOTYPE so you can do that more easily.
I was going to write up how to do that, but earlier in this thread Harry Hambrick already pointed to a Spectrum by Clif Oliver: www.intl-spectrum.com/Article/r310/Auditing_Database_Changes_with_UniVerse_Indexing_Subroutines. Kudos, Clif.
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
San Ignacio BZ
------------------------------
Thank you all for that info!
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
Thank you all for that info!
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
Here is our TOI document on Indexed Subroutines from when they were first introduced into UniVerse.
Thanks,
Jonathan
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
Here is our TOI document on Indexed Subroutines from when they were first introduced into UniVerse.
Thanks,
Jonathan
------------------------------
Jonathan Smith
UniData ATS
Rocket Support
------------------------------
Jonathon,
While we're on the subject & while I have your ear, thank the team for @IDX.IOTYPE for me.
Warm regards,
Chuck S
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
San Ignacio BZ
------------------------------
Yes on UV, triggers are documented/part of SQL engine.
look at HELP SQL CREATE TRIGGER / DROP TRIGGER.
You can use it against standard non SQL uv datafile.
be carefull, if you change the subr after create trigger you must drop/create.
Regards
------------------------------
Manu Fernandes
------------------------------
You can actually use a "master" globally cataloged subroutine that calls other subroutines based on how you activate the trigger.
We have about a dozen or so triggers on all sorts of files. Each file that has a trigger has it's own trigger subroutine. So for a customer file you might name this trigger "SR.CUSTOMER.FTRIG" (cataloged locally) which is called by "SR.MASTER.FTRIG" (cataloged globally).
We've found that you can actually re-compile these locally cataloged subroutines without having to drop/activate the trigger UNLESS your system is super busy AND the trigger is on a file that is being hit very hard, in which case you might end up having to bounce UniVerse. This may also be a feature of our old UV version too. I'm sure you'll find out soon enough - we did. Nowadays we arrange an outage to deploy trigger changes but thankfully this is not very often.
@Kathleen Hambrick: Ken Ford, my former colleague here wrote a really nice utility to control the trigger enable/disable each trigger for each of the insert/modify/delete and before/after conditions for all the files that we run triggers on. It has a nice -DROPALL option but sadly no -STARTALL. Ken has posted this code publicly in the past so it has to be out there if you search for his name and/or the "MASTER.FTRIG.CONTROL" program name.
Cheers,
Peter
------------------------------
Peter Cheney
Developer and Systems Superstar
Firstmac
Brisbane Qld Australia
------------------------------
CREATE-TRIGGER, LIST-TRIGGER, DELETE-TRIGGER
I do see the LIST.SICA command, which lists universe triggers on SQL files....do we not have triggers on regular PICK files in universe?
------------------------------
Kathleen Hambrick
Programmer at Colwell
------------------------------
If you haven't already found it, LIST.SICA filename will tell you some information
LIST.SICA CUSTOMER 10:29:18am 25 May 2022 Page 1
==========================================
Sica Region for Data File "CUSTOMER"
Revision: 4
Trigger "CUSTOMER.DELETE.FTRIG" is enabled, creator is "peter".
calls "*FMC*SR.MASTER.FTRIG" for Row After Delete
Trigger "CUSTOMER.UPDATE.FTRIG" is enabled, creator is "peter".
calls "*FMC*SR.MASTER.FTRIG" for Row After Update
Trigger "CUSTOMER.INSERT.FTRIG" is enabled, creator is "peter".
calls "*FMC*SR.MASTER.FTRIG" for Row After Insert
>
------------------------------
Peter Cheney
Developer and Systems Superstar
Firstmac
Brisbane Qld Australia
------------------------------
You can actually use a "master" globally cataloged subroutine that calls other subroutines based on how you activate the trigger.
We have about a dozen or so triggers on all sorts of files. Each file that has a trigger has it's own trigger subroutine. So for a customer file you might name this trigger "SR.CUSTOMER.FTRIG" (cataloged locally) which is called by "SR.MASTER.FTRIG" (cataloged globally).
We've found that you can actually re-compile these locally cataloged subroutines without having to drop/activate the trigger UNLESS your system is super busy AND the trigger is on a file that is being hit very hard, in which case you might end up having to bounce UniVerse. This may also be a feature of our old UV version too. I'm sure you'll find out soon enough - we did. Nowadays we arrange an outage to deploy trigger changes but thankfully this is not very often.
@Kathleen Hambrick: Ken Ford, my former colleague here wrote a really nice utility to control the trigger enable/disable each trigger for each of the insert/modify/delete and before/after conditions for all the files that we run triggers on. It has a nice -DROPALL option but sadly no -STARTALL. Ken has posted this code publicly in the past so it has to be out there if you search for his name and/or the "MASTER.FTRIG.CONTROL" program name.
Cheers,
Peter
------------------------------
Peter Cheney
Developer and Systems Superstar
Firstmac
Brisbane Qld Australia
------------------------------
What has been your experience using DEBUG or RAID on programs that write to files/tables having triggers?
It was a problem a while back, but I haven't tried it at UV11.
tia,
cds
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
San Ignacio BZ
------------------------------
What has been your experience using DEBUG or RAID on programs that write to files/tables having triggers?
It was a problem a while back, but I haven't tried it at UV11.
tia,
cds
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
San Ignacio BZ
------------------------------
Debugging code that writes to files with triggers is a pain. We're on UV10.3.4 but have played with UV11.2 and it's still the same.
Need to remember to always set a break point just beyond the write line. Sometimes I forget though haha.
Cheers,
Peter
------------------------------
Peter Cheney
Developer and Systems Superstar
Firstmac
Brisbane Qld Australia
------------------------------
Debugging code that writes to files with triggers is a pain. We're on UV10.3.4 but have played with UV11.2 and it's still the same.
Need to remember to always set a break point just beyond the write line. Sometimes I forget though haha.
Cheers,
Peter
------------------------------
Peter Cheney
Developer and Systems Superstar
Firstmac
Brisbane Qld Australia
------------------------------
re. "Debugging code that writes to files with triggers is a pain. We're on UV10.3.4 but have played with UV11.2 and it's still the same."
With the advent of @IDX.IOTYPE, is there any advantage to using formal UV Triggers instead of an index (usually with NO.NULLS) subroutine instead, as discussed earlier in this thread?
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
US
------------------------------
re. "Debugging code that writes to files with triggers is a pain. We're on UV10.3.4 but have played with UV11.2 and it's still the same."
With the advent of @IDX.IOTYPE, is there any advantage to using formal UV Triggers instead of an index (usually with NO.NULLS) subroutine instead, as discussed earlier in this thread?
------------------------------
Chuck Stevenson
DBA / SW Developer
Pomeroy
US
------------------------------
I am by no means a trigger or an indexing expert, so while I have found this discussion extremely educational, some if the items went a little beyond by skill level. I apologize ahead of time if the answer to my question was already covered and I either missed it or just plain didn’t understand.
From what I can gather, a trigger-based program gets ‘fired’ when a file gets updated (or whatever condition is defined in the trigger), while an index-based program would get run when the index itself gets updated. What then happens when/if I have to clear the indices on a file and rebuild them? Won’t that rerun the program if it’s index-based and double-up on whatever that program was supposed to do?
Brian
Sign up
Already have an account? Login
Welcome to the Rocket Forum!
Please log in or register:
Employee Login | Registration Member Login | RegistrationEnter your E-mail address. We'll send you an e-mail with instructions to reset your password.