Trigger: Trigger if someone INSERT,UPDATE and DELETE a table - sql

I have a trigger created that will log their username to ChangesLogtbl if they update, delete or insert in TblCurrentRec.
CREATE TRIGGER mytriggerforinsert
#username = username <------------------itried to place something like this
ON TblCurrentRec
AFTER INSERT
AS BEGIN
INSERT INTO ChangesLogtbl
values ('username', 'GETDATE')
END
GO
This works but I want this one to work on all tables within the schema. and also not to limit it on insert but to delete and update as well.
I tried using everything in and over the net and also copied and studied different sample but to no avail. I'm new to SQL and this is my very first time to create a trigger. Hope you guys can understand.
Thanks.

TO cover other DML,
ON TblCurrentRec
AFTER INSERT or UPDATE or DELETE
Coming to schema level coverage, i doubt you can have a single trigger for all tables in schema.Triggers should be written to each table.
If it where DDL we can use DATABASE TRIGGERS

You can use of cursors and the Information_Schema.Tables view to create triggers on all tables of a database.

Related

How to know all the actions taken on postgres SQL table?

I am looking for a way to know all the events occurred on a specific table without enabling postgres logs.
Just want to know weather the sequence of addition/deletion/ Modification.
Thanks
For audit trail in postgres you have to write an function and call it in a trigger, please have a look at wiki.postgresql.org/wiki/Audit_trigger , You will have to write a function stating that if an update or delete or insert is happening on a table it will trigger an action updating a audit table capturing required information such as ip address, query, old data, new data, timestamp of the action that has occured etc..
You can create triggers (see postgres docs) to observe all changes, e.g.:
CREATE TRIGGER insert_trigger AFTER INSERT ON my_table
EXECUTE PROCEDURE insert_function();
CREATE TRIGGER update_trigger AFTER UPDATE ON my_table
EXECUTE PROCEDURE update_function();
CREATE TRIGGER delete_trigger AFTER DELETE ON my_table
EXECUTE PROCEDURE delete_function();
or do this with just one function:
CREATE TRIGGER universal_trigger AFTER INSERT OR UPDATE OR DELETE ON my_table
EXECUTE PROCEDURE universal_function();

SQL Server: DonĀ“t execute a Trigger when the updater is another trigger

Here is the scenario:
There is Trigger A and Trigger B, both in the Person table. I can't trigger the Trigger A when the update on table Person comes from Trigger B.
Is there something, such as an IF that I could use to solve this situation?
Thanks in advance for any help!
Right at the start, I will warn you that having multiple triggers on one table is not a good idea. Try and merge the actions of the two triggers into one if possible. However, if that is not a solution for you, then read on for my version. (I am not certain if it is practically valid, but go ahead and give it a shot anyway)
CREATE TRIGGER triggerB
ON yourtable
FOR UPDATE
AS
BEGIN
ALTER TABLE table_name DISABLE TRIGGER triggerA
--your processing
ALTER TABLE table_name ENABLE TRIGGER triggerA
END
This question deals with disabling then enabling triggers inside a stored procedure. This is an application of the same in a trigger.
Disclaimer: I am counting on this to fail because altering a table while in a trigger defined on that same table seems like an impossible task. But I have no resources at hand to test my wacky theory, so please test it and let me know if I'm thinking too far outside the box.
I got it!
IF TRIGGER_NESTLEVEL(OBJECT_ID('TRIGGER_NAME')) = 0
BEGIN
-- Your Trigger STuff
END
Thanks for answers and comments.

SQL use temporary tables in trigger

I have a trigger in MSSQL Server 2008R2 :
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[trg_HosFile_Delete]
ON [dbo].[hosfile] FOR DELETE
AS
insert into #pys(pyGuid)
SELECT EntryGuid AS pyGuid FROM er000 AS er
insert into t2(C1) select pyGuid from #pys
After the trigger has executed the t2 table is empty. Why is it empty?
If I execute the query above without a trigger the t2 table is filled.
is there any problem with using a temporary table in a trigger?
Damien's answer is correct: you can use temporary tables in triggers, but it is strongly recommended to define them there, since the trigger can fire in various contexts.
If you use temporary tables in triggers, check for temporary table existence as you do not control the context and it might be already there:
IF OBJECT_ID('tempdb..#pys') IS NOT NULL
DROP TABLE #pys
Also, temporary tables can be created on the fly:
SELECT * INTO #tmp
FROM inserted
This is particularly useful when trigger contains dynamic SQL that needs to access inserted or deleted special tables which are not visible in the dynamic SQL scope.
Avoid using ##tmp (global temporary variables), as these are globally visible and can lead to trouble when multiple SPIDs are firing you trigger.
There's no problem using temp tables, provided that they're in scope at the time the trigger fires.
Given that the trigger can fire at any time, on any connection, the only scope that makes sense is within the body of the trigger:
ALTER TRIGGER [dbo].[trg_HosFile_Delete]
ON [dbo].[hosfile] FOR DELETE
AS
CREATE TABLE #pys (pyGuid uniqueidentifier not null/*I'm guessing*/)
insert into #pys(pyGuid)
SELECT EntryGuid AS pyGuid FROM er000 AS er
insert into t2(C1) select pyGuid from #pys
(To be honest, I'm not sure if you could access a temp table from an outer scope, and don't have an instance handy to test it. But, even if you can, it would make for a very brittle trigger)
If you use ##pys (notice the double # sign) it will be globally available after its creation. That might help in your case.
Try to use SELECT INTO to create and populate the temporary table. There are some restrictions when using a temp table inside a trigger.

Should I use the template from MS SQL Management Studio to create new triggers?

If you create a new trigger in MS SQL Management Studio by using the GUI, it gives you this template:
--====================================
-- Create database trigger template
--====================================
USE <database_name, sysname, AdventureWorks>
GO
IF EXISTS(
SELECT *
FROM sys.triggers
WHERE name = N'<trigger_name, sysname, table_alter_drop_safety>'
AND parent_class_desc = N'DATABASE'
)
DROP TRIGGER <trigger_name, sysname, table_alter_drop_safety> ON DATABASE
GO
CREATE TRIGGER <trigger_name, sysname, table_alter_drop_safety> ON DATABASE
FOR <data_definition_statements, , DROP_TABLE, ALTER_TABLE>
AS
IF IS_MEMBER ('db_owner') = 0
BEGIN
PRINT 'You must ask your DBA to drop or alter tables!'
ROLLBACK TRANSACTION
END
GO
Should I use this template?
I dont know anything about triggers, but I think I need to use them. The purpose in this case is that on an insert to the table, I need to update one of the fields.
Please help me get started!
OK to begin with that is the wrong template if you want an ordinary trigger that one is a trigger on making structural changes to the table itself.
If you decide to do a trigger that affects data (as opposed to structure), there are several things you need to know. First and by far the most critical, triggers operate on sets of data not one row at time. You must write any trigger to handle multiple row inserts.updates or deletes. If you end up with any code setting the value in inserted or deleted to a variable, there is a 99% chance it will not work properly if multiple records are involved.
What is inserted or deleted you ask? That is the next thing you need to know about triggers, there are two pseudotables (inserted and deleted) that are only available in a trigger (or an output clause) which contain the new information being inserted or the updated values (in the inserted table) and the old information being deleted or being changed by an update (in the deleted table). So an insert has values in inserted, a delete has values in deleted and an update has values in both. Use these in your trigger to pull the values you need to change.
Since you don't know anything about triggers, I would say no, don't use the template.
Read the books online page for Create Trigger and write the trigger by hand.
There is probably more in that template code than you actually need. Read the manual and keep it simple.
If you don't know anything about triggers then I would strongly suggest that you read up on them before implementing them. Get Triggers right and they can make your life a lot easier; get it wrong and Triggers will cause you a lot of trouble.
I would suggest starting off with this tutorial
http://www.sqlteam.com/article/an-introduction-to-triggers-part-i
You can use the above SQL as a template or you can simply write your own. I would suggest you write your own as you'll understand what you are doing. Obviously only do this after you have done some serious reading on triggers. Check out MSDN too

SQL Server 2005 Insert Trigger with Update Statement

I am currently not in a location to test any of this out but would like to know if this is an option so I can start designing the solution in my head.
I would like to create an insert trigger on a table. In this insert trigger, I would like to get values from the inserted virtual table and use them to UPDATE the same table. Would this work or would we enter some kind of infinite loop (even though the trigger is not for update commands).
As an example if a row was inserted (which represents a new rate/cost for a vendor) I would like to update the same table to expire the old rate/cost for that vendor. The expiration is necessary vs updating the record that already exists so a history of rates/costs can be kept for reporting purposes (not to mention that the current reporting infrastructure expects this type of thing to happen and we are migrating current reports/data to SQL Server).
Thanks!
If you have only an INSERT trigger and no UPDATE trigger then there isn't any problem, but I assume you want to catch also UPDATEs and perhaps even DELETEs.
The INSTEAD OF triggers are guaranteed not to behave recursively:
If an INSTEAD OF trigger defined on a
table executes a statement against the
table that would ordinarily fire the
INSTEAD OF trigger again, the trigger
is not called recursively
With and INSTEAD OF trigger you must do both the original INSERT and the UPDATE you desire.
This doesn't sound like it would cause any problems to me, providing you're not doing an INSERT in another UPDATE trigger.