SQL eventdata() - sql

when using a trigger in SQL SERVER 2005 the eventdata() always return a empty value.
only the date inserted in the Audit table, other fields are NULL valus
pls help me
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[TrigDip]
ON [dbo].[Dip]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
DECLARE #ed XML
SET #ed = EVENTDATA()
DECLARE #db varchar(1000)
set #db =EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)')
PRINT 'CREATE TABLE Issued.'
INSERT INTO Audit (PostTime, DatabaseName, Event, ObjectName, TSQL, Login)
VALUES
(
GetDate(),
#db,
EVENTDATA().value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'),
EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]', 'varchar(256)'),
EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)'),
CONVERT(nvarchar(100), CURRENT_USER)
)
END

EVENTDATA on MSDN states
EVENTDATA returns data only when referenced directly inside of a DDL or logon trigger. EVENTDATA returns null if it is called by other routines, even if those routines are called by a DDL or logon trigger.
Your trigger above is a DML AFTER trigger.
You need
CREATE TRIGGER TRG_CreateTable
ON DATABASE
FOR CREATE_TABLE
...

Related

SQL Server: using dm_exec_describe_first_result_set with table variable fires CREATE_TABLE trigger

I try to use sys.dm_exec_describe_first_result_set with query containing table variable to describe columns of the query.
But declare of table variable in this query is causing activation of DATABASE trigger for event AFTER CREATE_TABLE, which contains a calling of stored procedure with temp table.
Usual declare of table variable this trigger don't activate. Some ideas why is the trigger activated for table variable?
CREATE PROCEDURE SP1 AS
BEGIN
CREATE TABLE #A(b int)
INSERT INTO #A(b) VALUES(1)
DROP TABLE #A
END
GO
CREATE TRIGGER [CreateObjectDatabaseTrigger]
ON DATABASE
AFTER
CREATE_TABLE
AS
BEGIN
EXEC SP1
END
GO
ENABLE TRIGGER [CreateObjectDatabaseTrigger] ON DATABASE
DECLARE #SqlQuery NVARCHAR(MAX) = N'DECLARE #A TABLE (b int) SELECT * FROM #A'
SELECT error_message, name
FROM
sys.dm_exec_describe_first_result_set
(#SqlQuery, NULL, 0)
Result with enabled trigger: The metadata could not be determined because statement 'INSERT INTO #A(b) VALUES(1)' in procedure 'SP1' uses a temp table.
Triggers should not return result sets to the client. Doing so is deprecated behavior and will be removed from a future version of SQL Server per the documentation.
In this case, use PRINT to return the informational message instead of a result set. The side-effect of this practice is that sys.dm_exec_describe_first_result_set will return the desired meta-data:
CREATE TRIGGER [CreateObjectDatabaseTrigger]
ON DATABASE
AFTER
CREATE_TABLE
AS
BEGIN
PRINT 'Trigger activated';
END
GO
ENABLE TRIGGER [CreateObjectDatabaseTrigger] ON DATABASE;
DECLARE #SqlQuery NVARCHAR(MAX) = N'DECLARE #A TABLE (b int) SELECT * FROM #A';
SELECT error_message, name
FROM sys.dm_exec_describe_first_result_set
(#SqlQuery, NULL, 0);

SQL Server - DDL Trigger to modify Table after its creation

I have a 3rd party program which exports data to SQL Server.
However, such program can not insert, but drops and recreates each tables with the data each time it is processed.
There is a specific schema for that.
I need to run modifications on such table on SQL each time it is re-created.
I have been trying using a DDL trigger on Create, which just writes the name of the table to a LOG if it's in the target schema:
CREATE TRIGGER [tCREATE_TABLE] ON DATABASE
FOR CREATE_TABLE
AS
DECLARE #data XML;
DECLARE #schema sysname;
DECLARE #schema_s nvarchar(128);
DECLARE #object sysname;
DECLARE #object_s nvarchar(128);
DECLARE #eventType sysname;
SET #data = EVENTDATA();
SET #eventType = #data.value('(/EVENT_INSTANCE/EventType)[1]',
'sysname');
SET #schema = #data.value('(/EVENT_INSTANCE/SchemaName)[1]','sysname');
SET #schema_s = CAST(#schema as nvarchar(128));
SET #object = #data.value('(/EVENT_INSTANCE/ObjectName)[1]','sysname');
SET #object_s = CAST(#object as nvarchar(128));
-- COMMIT should unlock the table...??
COMMIT
IF #schema_s = 'TARGET_SCHEMA'
INSERT INTO [TARGET_SCHEMA].[UpdateLOG](TabName,LOAD_UPDATEDATE,LOAD_USER)
VALUES (#object_s,GETDATE(),CURRENT_USER)
-- this is the procedure that modifies the target table
EXEC [ProcessTableProcedure]
#targettab = #object_s
GO
This works for writing to a log, but as soon as I add call the processing procedure it returns an error.
At the end of the trigger, the modifying procedure won't find the table - since the transaction is not committed yet.
I have put a COMMIT before that, but then nothing happens (procedure is not run).
I assume the trigger ends after the COMMIT...?
Any help?

SQL Server 2008 Create Trigger after insert... return id... called stored procedure

I just want a SIMPLE sql server trigger (after insert) to get the ID back from the table that was inserted into... So algorithm:
new record is inserted into table
trigger is called
trigger takes id from inserted record and called stored procedure
My failed attempt is below:
CREATE TRIGGER [dbo].[insertNewMarket]
ON [dbo].[markets]
AFTER insert
AS
BEGIN
declare #marketID int
SET NOCOUNT ON;
--SELECT ID from inserted
--set #marketID = Inserted.ID--get the inserted id and pass to stored proc
exec marketInsert #marketID
END
GO
In trigger, you can access an table with the name "INSERTED", which will have the newly inserted record details. small example below
CREATE TRIGGER [dbo].[insertNewMarket]
ON [dbo].[markets]
AFTER insert
AS
BEGIN
declare #marketID int
SET NOCOUNT ON;
SELECT #marketID = ID from inserted
exec marketInsert #marketID
END
GO

How to get sql statement in trigger

I have insert, update, delete triggers for every tables to logging actions.
I am retrieving before and after datas from deleted, inserted and wrapping these into xml.
But some logs can't show before and update values.
My sql statement is:
USE [cop]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[Delete] ON [dbo].[Seanslar]
AFTER DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE #deleted AS XML
SET #deleted = (select * from deleted for xml AUTO, ELEMENTS XSINIL)
DECLARE #logIslem TINYINT
SET #logIslem = 3
DECLARE #tableName VARCHAR(200)
SELECT #tableName = OBJECT_SCHEMA_NAME( parent_id ) + '.' + OBJECT_NAME( parent_id )
FROM sys.triggers
WHERE object_id = ##PROCID
DECLARE #xmlToChar NVARCHAR(MAX)
SET #xmlToChar = CAST(#deleted AS nvarchar(MAX))
IF LEN(#xmlToChar)<10
BEGIN
IF EXISTS(select * from deleted)
select #xmlToChar = CAST(seans_id AS NVARCHAR(MAX)) from deleted
ELSE
SET #xmlToChar = 'Deleted is empty!'
END
DECLARE #allXml AS XML
SET #allXml = '<'+#tableName+'>'+ #xmlToChar +'</'+#tableName+'>'
INSERT INTO [dbo].[Logla]
([logIslem], [trgKullanici_id], [tabloAdi], [logXml])
VALUES
(#logIslem, SUSER_NAME(), #tableName, #allXml)
END
Is there any way to learn "sql statement" executed inside trigger?
There is no practical way to capture the executing SQL statement text inside of a DML Trigger fired by that statement.
You can do this with a DDL (metadata) Trigger, but not a DML (normal) Trigger.
And yes, there are one or two very impractical ways to do it, but I really do not recommend them unless:
You are very, very SQL proficient, and
You really, really need to get it, and
You can afford a lot of development and testing time

SQL Server Create Login using inserted values from Trigger

I have a table of users in sql serevr 2012 and wish to create corresponding database login users using inserted values from an insert trigger on the users table.
Everything seems to work ok except that I cannot properly use a referenced value in the inserted table
though I have tested the value to make sure it exists
is it possible that the create login procedure cannot accept variables
ALTER TRIGGER [dbo].[addsyslogin]
ON [dbo].[Users]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
SET QUOTED_IDENTIFIER OFF;
Declare #u varchar(10);
SELECT #u=i.userid from inserted i;
print #u;
CREATE LOGIN [#u] WITH PASSWORD='water123GH', DEFAULT_DATABASE=[waterdb], DEFAULT_LANGUAGE=[British], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON
END
I have researched on quoted_identifiers but I still have this problem.
What happens is that a database user is actually created with userid=#u instead of the value in #u.
Thanks for your notes and feedback
try this:
SET #SQL = 'CREATE LOGIN ' + #u+ ' WITH PASSWORD = ''water123GH'', DEFAULT_DATABASE=[waterdb], DEFAULT_LANGUAGE=[British], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON';
EXECUTE(#SQL);
This is a curious thing to do, but you need to...
allow for multiple rows
escalate privileges
use dynamic SQL
Other notes:
I'd suggest that you need a separate stored procedure in master called by your trigger to deal with the escalation
If you don't require escalation, then your privileges are too high
Rough code:
ALTER TRIGGER [dbo].[addsyslogin] ON [dbo].[Users] FOR INSERT
WITH EXECUTE AS --soemthing
AS
SET NOCOUNT ON;
Declare #u varchar(10), #uid int;
SELECT TOP 1 #uid = i.userid, #u = i.userid
FROM inserted i
ORDER BY i.userid;
WHILE #u IS NOT NULL
BEGIN
SET #SQL = 'CREATE LOGIN ' + #u+ ' WITH PASSWORD = ''water123GH'', DEFAULT_DATABASE=[waterdb], DEFAULT_LANGUAGE=[British], CHECK_EXPIRATION=OFF, CHECK_POLICY=ON';
EXECUTE(#SQL);
SET #u = NULL;
SELECT TOP 1 #uid = i.userid, #u = i.userid
FROM inserted i
WHERE i.userid > #uid
ORDER BY i.userid;
END
GO