Drop/Create Triggers in a Transaction Question - Will the trigger run after - sql

I would like to inquire about the behavior of a trigger (let's say "after update" trigger) that is dropped at the beginning of a transaction and then re-created at the end of a transaction,- specifically, will the trigger run during the commit phase of the transaction (assuming that in the middle of the transaction I executed some scripts that would normally trigger the trigger)?
Consider this example.
Start Transaction
Drop trigger
Run scripts that make changes to the table that would normally trigger the (dropped) trigger
Re-create the (dropped) trigger
Commit Transaction
At line #5, when database commits entire transaction, will the re-created trigger run or not?
UPDATE
I would like to re-phrase the question if this is not possible/or good idea to do it this way. Instead of dropping/re-creating, I believe a better solution is to disable/enable the trigger. In this, when the trigger is enabled, will it run at the end of the transaction?
UPDATE 2
As suggested by everyone, for my scenario do this:
Start TX
disable trig, run SQL, enable trig
Commit TX
The trigger will not fire which is what I want.

The trigger will not run if you ENABLE the trigger between the DML statement and the COMMIT; For example, this will not cause the trigger to execute:
BEGIN TRANSACTION;
ALTER TABLE [dbo].[myTable] DISABLE TRIGGER [trg_trgtest]
UPDATE [dbo].[myTable]
SET [language] = 'fr'
WHERE id = 6
ALTER TABLE [dbo].[myTable] ENABLE TRIGGER [trg_trgtest]
COMMIT;

Dropping a trigger places an exclusive metadata lock (Sch-M) on the table, preventing any queries or DML, which all require a Schema Stability Lock (Sch-S), for the duration of the transaction.
EG
use tempdb
go
drop table if exists foo
go
create table foo(id int primary key)
go
create trigger tg_foo on foo after insert
as
begin
select 'tg_foo trigger running' msg
end
go
begin transaction
go
drop trigger tg_foo
go
select o.name, o.type_desc, request_mode
from sys.dm_tran_locks tl
join sys.objects o
on o.object_id = tl.resource_associated_entity_id
where request_session_id = ##spid
and o.is_ms_shipped = 0
optputs
name type_desc request_mode
------------------- ----------- --------------
foo USER_TABLE Sch-M
(1 row affected)
So when you drop a trigger at the beginning of a transaction, all access to that table will be blocked until you commit or rollback the transaction.
And so
will the trigger run during the commit phase of the transaction
(assuming that in the middle of the transaction I executed some
scripts that would normally trigger the trigger)?
So on commit, the script that would normally "trigger the trigger" will become unblocked, and run, triggering the trigger as normal.

If you disable a trigger, then execute and commit a transaction, then re-enable the trigger, the trigger will not "run" for the already completed transaction.

Related

How does the triggers fires in sql?

If I have a trigger like the following one:
CREATE TRIGGER T
AFTER UPDATE ON SERVER
FOR EACH ROW
WHEN condition
BEGIN
INSERT INTO tab1 ... VALUES (...)
UPDATE SERVER SET freememory = freememory + 2
DELETE tab2 WHERE ID = 2
END;
How does the triggers are fired? I mean, once the second query (UPDATE SERVER ...) is executed I should re-call the execution of the same trigger.
It isn't clear to me if before re-executing the trigger I execute the DELETE tab2 (and so I wait the end of my actual trigger), or if the trigger is re-executed right after the update query and so all the delete are postponed.
I am considering a general SQL language, not related to a specific vendor.
Thank you
The triggers are activated when asked: some before and some after. If we create a trigger that activates after an update then the trigger will activate itself

Does anyone know why this trigger is not working?

create or replace NONEDITIONABLE TRIGGER SetNapomena
BEFORE INSERT
ON stavkafakture
FOR EACH ROW
DECLARE
V_napomena VARCHAR2(20);
BEGIN
EXECUTE IMMEDIATE 'ALTER TRIGGER zabranjeno DISABLE';
SELECT napomena INTO V_napomena
FROM faktura
WHERE brojfakture =:NEW.brojfakture;
:NEW.napomena := V_napomena;
EXECUTE IMMEDIATE 'ALTER TRIGGER zabranjeno ENABLE';
END;
When I insert into a table (in this case stavkafakture) I get this error:
Cannot commit in a trigger
I did some research and added Pragma Autonomous Transaction and commit, but after adding them I try to insert a row in the table it loads forever and never works.
It stays in load forever.
Does anyone know why?
In Oracle DDL statement like CREATE, ALTER, DROP generate an explicit commit.
IE if you issue this kind of statement this does not requires a COMMIT nor a ROLLBACK :
CREATE TABLE MyTable(MyField NUMBER);
This will create the MyTable table and cannot be ROLLBACK.
This is a limitation of Oracle that other RDBMS like PostreSQL doesn't have.

Should i commit at the end of the procedure which is called by an oracle scheduler job

I am running an oracle JOB which will run a PROCEDURE to CREATE TRUNCATE INSERT DROP some relevant tables.
Is this the best way to do a functionality like this ?
Should I Commit at the end of the procedure or not ?
CREATE OR REPLACE Procedure PR_NAME
IS
BEGIN
CREATE TABLE TABLE_1_BAC AS SELECT * FROM TABLE1_VIA_DBLINK;
TRUNCATE TABLE TABLE_1;
INSERT INTO TABLE_1 SELECT * FROM TABLE_1_BAC;
DROP TABLE TABLE_1_BAC;
--COMMIT;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;
To create TABLE_1 only once for present data :
CREATE TABLE TABLE_1 AS SELECT * FROM TABLE1_VIA_DBLINK;
and creating an insert trigger for TABLE1_VIA_DBLINK, populating TABLE_1 through this trigger for new datas, and to get rid of this job and procedure seems more feasible.
As you stay in this job, perhaps you'll wait for huge data to be inserted.
By the way, if you insist on using this job, you don't need to issue commit, since and there's already an implicit commit exists inside job mechanism.
What kind of job do you use? JOB or SCHEDULER JOB?
I don't see any reason to DROP/CREATE the table. I don't see any reason why you use the intermediate table at all.
Simply make
CREATE OR REPLACE Procedure PR_NAME
IS
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE_1';
INSERT INTO TABLE_1 SELECT * FROM TABLE1_VIA_DBLINK;
COMMIT;
END;
You don't need any exception handler. In case of JOB you will not see the exception anyway. In case of SCHEDULER JOB you can see exception in views
*_SCHEDULER_JOB_LOG
*_SCHEDULER_JOB_RUN_DETAILS
If you make just this kind of operation you should consider MATERIALIZED VIEW which basically make the same: TRUNCATE and INSERT INTO ... SELECT * FROM ...
No. You don't need to commit.
Those commands are DDL (Data Definition Language) in SQL. So Oracle Database will issue a commit together with the command.
DML (Data Manipulating Language) - like SELECT, UPDATE, INSERT, DELETE requires a commit.
In a scenario, where you will update, delete and insert records. Then you ran a create table command. The records inserted, updated and deleted will be committed (save) to the database.

Is it possible to rollback DELETE, DROP and TRUNCATE?

We can rollback a delete query but not so for truncate and drop. When I execute queries then successfully done with rollback in delete, drop & truncate.
We can rollback the data in conditions of Delete, Truncate & Drop.
But must be used Begin Transaction before executing query Delete, Drop & Truncate.
Here is example:
Create Database Ankit
Create Table Tbl_Ankit(Name varchar(11))
insert into tbl_ankit(name) values('ankit');
insert into tbl_ankit(name) values('ankur');
insert into tbl_ankit(name) values('arti');
Select * From Tbl_Ankit
/*======================For Delete==================*/
Begin Transaction
Delete From Tbl_Ankit where Name='ankit'
Rollback
Select * From Tbl_Ankit
/*======================For Truncate==================*/
Begin Transaction
Truncate Table Tbl_Ankit
Rollback
Select * From Tbl_Ankit
/*======================For Drop==================*/
Begin Transaction
Drop Table Tbl_Ankit
Rollback
Select * From Tbl_Ankit
For MySql:
13.3.2 Statements That Cannot Be Rolled Back
Some statements cannot be rolled back. In general, these include data definition language (DDL) statements, such as those that create or drop databases, those that create, drop, or alter tables or stored routines.
You should design your transactions not to include such statements. If you issue a statement early in a transaction that cannot be rolled back, and then another statement later fails, the full effect of the transaction cannot be rolled back in such cases by issuing a ROLLBACK statement.
https://dev.mysql.com/doc/refman/8.0/en/cannot-roll-back.html
All of the above 3 transactions can be rolled back because all of them generate detail log. See this SO answer for more information. And this blog for detailed explanation with examples.
DELETE(DML)-------------------
Used to delete the tuples(row) of the table and have facility to DELETE ONE OR
MULTIPLE ROW USING WHERE CLAUSE
delete EX ->
 delete from emp ;
it will delete all the row of table
 delete from emp where id = 2;
it will delete one row
----------------------Drop(DDL)-------------------
This command will delete the whole structure of table with data so that's why it
is very important or crucial command and the access is to this command is only
to database administrator (DBA)
dropEX -> DROP EMP1;
it will vanish whole table with structure
-------------------TRUNCATE(DDL)----------------
Used to delete all rows (tuple) of the table.
truncate EX -> TRUNCATE EMP1;
----------------------QUESTIONS-------------------
QUES 1: IF WE CAN DELETE ALL ROWS FROM BOTH 'DELETE' COMMAND AND
'TRUNCATE' COMMAND THEN WHAT IS THE DIFFERENCE
DELETE AND TRUNCATE DIFFERENCE
DELETE command is DML command and TRUNCATE is DDL
TRUNCTE command will delete all rows because we can not use where clause
with truncate but WHERE clause can be applied to DELETE command and can
delete one or more rows through where condition
QUES 2: WHY TRUNCATE IS DDL ALTHOUGH IT IS WORKING ON DATA AND
DELETE IS DML IT IS ALSO WORKING ON DATA?
ANSWER:
 When TRUNCATE Command deletes all the row then we can never ROLLBACK
our deleted data because in truncate COMMIT is called implicitly
 But in the case of delete the log(backend file) is created from where you can get
your data ROLLBACK if deleted by mistake
 REMEMBER: In DELETE case ROLLBACK can be done only before the COMMIT

SQL triggers, invoke stored proc when an item is inserted/updated/deleted

I want to use triggers but is it possible to use a single trigger for insert/update/delete... I have done it for Delete. See below.
ALTER TRIGGER [dbo].[CleanUpDate]
ON [dbo].[Marks]
FOR DELETE
AS
BEGIN
DELETE FROM Grades
FROM Grades
JOIN deleted ON Grades.ID = deleted.ID
END
Thanks
Yes, see the ALTER TRIGGER reference.
ALTER TRIGGER [dbo].[CleanUpDate]
ON [dbo].[Marks]
FOR DELETE, UPDATE, INSERT
AS
-- ...