I want this trigger to insert data in audit table as well as to throw error. But this only raises error but...
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
This is the trigger to check if the actual salary is greater than maximum salary. But it only raised the error and did not record the data in audit table. I want this trigger to insert the data as well as to raise the error.
Create or replace trigger trg_audit
BEFORE UPDATE ON lds_placement
for each row
BEGIN
if :NEW.actual_salary>:new.max_salary then
insert into pradip_audit_table(audit_date, table_name, operation_type,
primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal )
values (sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL'));
raise_application_error(-20111, 'Salary cannot be more than maximum
salary');
end if;
end;
oracle
add a comment |
This is the trigger to check if the actual salary is greater than maximum salary. But it only raised the error and did not record the data in audit table. I want this trigger to insert the data as well as to raise the error.
Create or replace trigger trg_audit
BEFORE UPDATE ON lds_placement
for each row
BEGIN
if :NEW.actual_salary>:new.max_salary then
insert into pradip_audit_table(audit_date, table_name, operation_type,
primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal )
values (sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL'));
raise_application_error(-20111, 'Salary cannot be more than maximum
salary');
end if;
end;
oracle
add a comment |
This is the trigger to check if the actual salary is greater than maximum salary. But it only raised the error and did not record the data in audit table. I want this trigger to insert the data as well as to raise the error.
Create or replace trigger trg_audit
BEFORE UPDATE ON lds_placement
for each row
BEGIN
if :NEW.actual_salary>:new.max_salary then
insert into pradip_audit_table(audit_date, table_name, operation_type,
primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal )
values (sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL'));
raise_application_error(-20111, 'Salary cannot be more than maximum
salary');
end if;
end;
oracle
This is the trigger to check if the actual salary is greater than maximum salary. But it only raised the error and did not record the data in audit table. I want this trigger to insert the data as well as to raise the error.
Create or replace trigger trg_audit
BEFORE UPDATE ON lds_placement
for each row
BEGIN
if :NEW.actual_salary>:new.max_salary then
insert into pradip_audit_table(audit_date, table_name, operation_type,
primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal )
values (sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL'));
raise_application_error(-20111, 'Salary cannot be more than maximum
salary');
end if;
end;
oracle
oracle
asked Nov 16 '18 at 11:57
Pradeep Kaji ThapaPradeep Kaji Thapa
61
61
add a comment |
add a comment |
3 Answers
3
active
oldest
votes
I advise use autonomic transaction in separate procedure for insert into audit table for this case.
There is documentation
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm
Problem is that you do not make commit after insert. And you can't do this in trigger. I'd prefer make log in autonomic transaction and this should help.
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
add a comment |
Whatever you do in the trigger will follow the fate of the whole transaction.
If you insert the data and then raise an exception, the whole operation will be rolled back.
You need to perform the insert in ANOTHER TRANSACTION. oracle allows you to define functions and procedures that run in a separate transaction from the one of the calling program. You can even define these procedures as local procedures.
This is what you need:
Create or replace trigger trg_audit
AFTER UPDATE ON lds_placement
for each row
declare
procedure WriteAuditLog is
pragma autonomous_transaction;
begin
insert into pradip_audit_table(
audit_date, table_name, operation_type, primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal
)
values
(
sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL')
);
-- you can't leave a autonomous_transaction function without committing or rolling back:
-- if you leave the transaction open you get an error!
commit;
exception when others then
rollback;
raise;
end WriteAuditLog;
BEGIN
if :NEW.actual_salary>:new.max_salary then
WriteAuditLog;
raise_application_error(-20111, 'Salary cannot be more than maximum salary');
end if;
end;
Please note that I changed the trigger to be run AFTER the statement, not BEFORE.
- There could be MULTIPLE before triggers on your table
- Every BEFORE trigger has the opportunity of changing the actual data that will be written
- you have no guarantee that your trigger will be the last one to be executed.
It is entirely possible that there is another trigger that would cap the salary to the maximum limit and would insert a record that doesn't violate the rule: your trigger, if is run before this one, would make this second trigger useless.
Another thing that could happen is that another trigger gets run after the "before" data has passed your check, and this second trigger could change the data by, for example, doubling the salary and write data that violates your check, regardless of what your trigger is supposed to do.
AFTER triggers can't change the data, since it has already been written, so the right place for this kind of checks, and for logging, is an AFTER trigger.
Notice that is you raise an exception the update command will be rolled back even if you are in an AFTER trigger: don't let the "AFTER" word misguide you.
add a comment |
From Documentation:
In most cases, if a trigger runs a statement that raises an exception,
and the exception is not handled by an exception handler, then the
database rolls back the effects of both the trigger and its triggering
statement.
Oracle creates an implicit savepoint before your update
statement, and if either update or trigger cause an exception, then the transaction is rolled back to that savepoint. The solution is to create a separate procedure for your insert, mark it as pragma AUTONOMOUS_TRANSACTION and perform a commit within that procedure; then the data you've inserted won't be rolled back when the trigger fails.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337446%2fi-want-this-trigger-to-insert-data-in-audit-table-as-well-as-to-throw-error-but%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I advise use autonomic transaction in separate procedure for insert into audit table for this case.
There is documentation
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm
Problem is that you do not make commit after insert. And you can't do this in trigger. I'd prefer make log in autonomic transaction and this should help.
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
add a comment |
I advise use autonomic transaction in separate procedure for insert into audit table for this case.
There is documentation
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm
Problem is that you do not make commit after insert. And you can't do this in trigger. I'd prefer make log in autonomic transaction and this should help.
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
add a comment |
I advise use autonomic transaction in separate procedure for insert into audit table for this case.
There is documentation
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm
Problem is that you do not make commit after insert. And you can't do this in trigger. I'd prefer make log in autonomic transaction and this should help.
I advise use autonomic transaction in separate procedure for insert into audit table for this case.
There is documentation
https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm
Problem is that you do not make commit after insert. And you can't do this in trigger. I'd prefer make log in autonomic transaction and this should help.
answered Nov 16 '18 at 12:15
Yevhen ZhovtonohYevhen Zhovtonoh
1764
1764
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
add a comment |
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
That was useful. Thank you for your help.
– Pradeep Kaji Thapa
Nov 17 '18 at 6:16
add a comment |
Whatever you do in the trigger will follow the fate of the whole transaction.
If you insert the data and then raise an exception, the whole operation will be rolled back.
You need to perform the insert in ANOTHER TRANSACTION. oracle allows you to define functions and procedures that run in a separate transaction from the one of the calling program. You can even define these procedures as local procedures.
This is what you need:
Create or replace trigger trg_audit
AFTER UPDATE ON lds_placement
for each row
declare
procedure WriteAuditLog is
pragma autonomous_transaction;
begin
insert into pradip_audit_table(
audit_date, table_name, operation_type, primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal
)
values
(
sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL')
);
-- you can't leave a autonomous_transaction function without committing or rolling back:
-- if you leave the transaction open you get an error!
commit;
exception when others then
rollback;
raise;
end WriteAuditLog;
BEGIN
if :NEW.actual_salary>:new.max_salary then
WriteAuditLog;
raise_application_error(-20111, 'Salary cannot be more than maximum salary');
end if;
end;
Please note that I changed the trigger to be run AFTER the statement, not BEFORE.
- There could be MULTIPLE before triggers on your table
- Every BEFORE trigger has the opportunity of changing the actual data that will be written
- you have no guarantee that your trigger will be the last one to be executed.
It is entirely possible that there is another trigger that would cap the salary to the maximum limit and would insert a record that doesn't violate the rule: your trigger, if is run before this one, would make this second trigger useless.
Another thing that could happen is that another trigger gets run after the "before" data has passed your check, and this second trigger could change the data by, for example, doubling the salary and write data that violates your check, regardless of what your trigger is supposed to do.
AFTER triggers can't change the data, since it has already been written, so the right place for this kind of checks, and for logging, is an AFTER trigger.
Notice that is you raise an exception the update command will be rolled back even if you are in an AFTER trigger: don't let the "AFTER" word misguide you.
add a comment |
Whatever you do in the trigger will follow the fate of the whole transaction.
If you insert the data and then raise an exception, the whole operation will be rolled back.
You need to perform the insert in ANOTHER TRANSACTION. oracle allows you to define functions and procedures that run in a separate transaction from the one of the calling program. You can even define these procedures as local procedures.
This is what you need:
Create or replace trigger trg_audit
AFTER UPDATE ON lds_placement
for each row
declare
procedure WriteAuditLog is
pragma autonomous_transaction;
begin
insert into pradip_audit_table(
audit_date, table_name, operation_type, primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal
)
values
(
sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL')
);
-- you can't leave a autonomous_transaction function without committing or rolling back:
-- if you leave the transaction open you get an error!
commit;
exception when others then
rollback;
raise;
end WriteAuditLog;
BEGIN
if :NEW.actual_salary>:new.max_salary then
WriteAuditLog;
raise_application_error(-20111, 'Salary cannot be more than maximum salary');
end if;
end;
Please note that I changed the trigger to be run AFTER the statement, not BEFORE.
- There could be MULTIPLE before triggers on your table
- Every BEFORE trigger has the opportunity of changing the actual data that will be written
- you have no guarantee that your trigger will be the last one to be executed.
It is entirely possible that there is another trigger that would cap the salary to the maximum limit and would insert a record that doesn't violate the rule: your trigger, if is run before this one, would make this second trigger useless.
Another thing that could happen is that another trigger gets run after the "before" data has passed your check, and this second trigger could change the data by, for example, doubling the salary and write data that violates your check, regardless of what your trigger is supposed to do.
AFTER triggers can't change the data, since it has already been written, so the right place for this kind of checks, and for logging, is an AFTER trigger.
Notice that is you raise an exception the update command will be rolled back even if you are in an AFTER trigger: don't let the "AFTER" word misguide you.
add a comment |
Whatever you do in the trigger will follow the fate of the whole transaction.
If you insert the data and then raise an exception, the whole operation will be rolled back.
You need to perform the insert in ANOTHER TRANSACTION. oracle allows you to define functions and procedures that run in a separate transaction from the one of the calling program. You can even define these procedures as local procedures.
This is what you need:
Create or replace trigger trg_audit
AFTER UPDATE ON lds_placement
for each row
declare
procedure WriteAuditLog is
pragma autonomous_transaction;
begin
insert into pradip_audit_table(
audit_date, table_name, operation_type, primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal
)
values
(
sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL')
);
-- you can't leave a autonomous_transaction function without committing or rolling back:
-- if you leave the transaction open you get an error!
commit;
exception when others then
rollback;
raise;
end WriteAuditLog;
BEGIN
if :NEW.actual_salary>:new.max_salary then
WriteAuditLog;
raise_application_error(-20111, 'Salary cannot be more than maximum salary');
end if;
end;
Please note that I changed the trigger to be run AFTER the statement, not BEFORE.
- There could be MULTIPLE before triggers on your table
- Every BEFORE trigger has the opportunity of changing the actual data that will be written
- you have no guarantee that your trigger will be the last one to be executed.
It is entirely possible that there is another trigger that would cap the salary to the maximum limit and would insert a record that doesn't violate the rule: your trigger, if is run before this one, would make this second trigger useless.
Another thing that could happen is that another trigger gets run after the "before" data has passed your check, and this second trigger could change the data by, for example, doubling the salary and write data that violates your check, regardless of what your trigger is supposed to do.
AFTER triggers can't change the data, since it has already been written, so the right place for this kind of checks, and for logging, is an AFTER trigger.
Notice that is you raise an exception the update command will be rolled back even if you are in an AFTER trigger: don't let the "AFTER" word misguide you.
Whatever you do in the trigger will follow the fate of the whole transaction.
If you insert the data and then raise an exception, the whole operation will be rolled back.
You need to perform the insert in ANOTHER TRANSACTION. oracle allows you to define functions and procedures that run in a separate transaction from the one of the calling program. You can even define these procedures as local procedures.
This is what you need:
Create or replace trigger trg_audit
AFTER UPDATE ON lds_placement
for each row
declare
procedure WriteAuditLog is
pragma autonomous_transaction;
begin
insert into pradip_audit_table(
audit_date, table_name, operation_type, primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal
)
values
(
sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL')
);
-- you can't leave a autonomous_transaction function without committing or rolling back:
-- if you leave the transaction open you get an error!
commit;
exception when others then
rollback;
raise;
end WriteAuditLog;
BEGIN
if :NEW.actual_salary>:new.max_salary then
WriteAuditLog;
raise_application_error(-20111, 'Salary cannot be more than maximum salary');
end if;
end;
Please note that I changed the trigger to be run AFTER the statement, not BEFORE.
- There could be MULTIPLE before triggers on your table
- Every BEFORE trigger has the opportunity of changing the actual data that will be written
- you have no guarantee that your trigger will be the last one to be executed.
It is entirely possible that there is another trigger that would cap the salary to the maximum limit and would insert a record that doesn't violate the rule: your trigger, if is run before this one, would make this second trigger useless.
Another thing that could happen is that another trigger gets run after the "before" data has passed your check, and this second trigger could change the data by, for example, doubling the salary and write data that violates your check, regardless of what your trigger is supposed to do.
AFTER triggers can't change the data, since it has already been written, so the right place for this kind of checks, and for logging, is an AFTER trigger.
Notice that is you raise an exception the update command will be rolled back even if you are in an AFTER trigger: don't let the "AFTER" word misguide you.
answered Nov 16 '18 at 12:36
Carlo SirnaCarlo Sirna
88147
88147
add a comment |
add a comment |
From Documentation:
In most cases, if a trigger runs a statement that raises an exception,
and the exception is not handled by an exception handler, then the
database rolls back the effects of both the trigger and its triggering
statement.
Oracle creates an implicit savepoint before your update
statement, and if either update or trigger cause an exception, then the transaction is rolled back to that savepoint. The solution is to create a separate procedure for your insert, mark it as pragma AUTONOMOUS_TRANSACTION and perform a commit within that procedure; then the data you've inserted won't be rolled back when the trigger fails.
add a comment |
From Documentation:
In most cases, if a trigger runs a statement that raises an exception,
and the exception is not handled by an exception handler, then the
database rolls back the effects of both the trigger and its triggering
statement.
Oracle creates an implicit savepoint before your update
statement, and if either update or trigger cause an exception, then the transaction is rolled back to that savepoint. The solution is to create a separate procedure for your insert, mark it as pragma AUTONOMOUS_TRANSACTION and perform a commit within that procedure; then the data you've inserted won't be rolled back when the trigger fails.
add a comment |
From Documentation:
In most cases, if a trigger runs a statement that raises an exception,
and the exception is not handled by an exception handler, then the
database rolls back the effects of both the trigger and its triggering
statement.
Oracle creates an implicit savepoint before your update
statement, and if either update or trigger cause an exception, then the transaction is rolled back to that savepoint. The solution is to create a separate procedure for your insert, mark it as pragma AUTONOMOUS_TRANSACTION and perform a commit within that procedure; then the data you've inserted won't be rolled back when the trigger fails.
From Documentation:
In most cases, if a trigger runs a statement that raises an exception,
and the exception is not handled by an exception handler, then the
database rolls back the effects of both the trigger and its triggering
statement.
Oracle creates an implicit savepoint before your update
statement, and if either update or trigger cause an exception, then the transaction is rolled back to that savepoint. The solution is to create a separate procedure for your insert, mark it as pragma AUTONOMOUS_TRANSACTION and perform a commit within that procedure; then the data you've inserted won't be rolled back when the trigger fails.
answered Nov 16 '18 at 12:21
TimekillerTimekiller
1,87111112
1,87111112
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337446%2fi-want-this-trigger-to-insert-data-in-audit-table-as-well-as-to-throw-error-but%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown