Is there a way to run some function like a trigger when a table is created in the database in SQL SERVER 2008?
Yes, it's called a DDL trigger. The documentation for CREATE TRIGGER has a sample for DROP_SYNONYM (a very questionable choice for an example) but you'll want the CREATE_TABLE event instead. A better starting point in understanding how they work is probably here:
http://msdn.microsoft.com/en-us/library/ms190989.aspx
If you have more specific details, e.g. what exactly do you want to pass to this function (I assume you mean procedure), or what does the procedure do, we can provide more useful and specific help.
Yes a DDL Trigger. For example, here is some code I written to prevent some tables from being modified:
PRINT N'Create DDL trigger to prevent changes to various tables'
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER NoEditCertainTables ON DATABASE
FOR DROP_TABLE, ALTER_TABLE, CREATE_TABLE
AS
SET CONCAT_NULL_YIELDS_NULL ON
DECLARE #AffectedTable varchar(255)
SELECT #AffectedTable = EVENTDATA().value('(/EVENT_INSTANCE/ObjectName)[1]','nvarchar(100)')
--This is the name of the table(s) you dont want messed with
IF (#AffectedTable IN ('Table1','Table2','Table3'))
BEGIN
ROLLBACK;
END
SET CONCAT_NULL_YIELDS_NULL OFF
GO
Related
I have a trigger in sql server that contains more then thousand lines of code like
CREATE TRIGGER [dbo].[xyz] ON [dbo].[abc]
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
--Here more then 100 field is there.
DECLARE #ErrMsg NVARCHAR(2000)
--
--
DECLARE #IsPublished BIT
DECLARE #ParentVersionedTemplateID UNIQUEIDENTIFIER
--
--
Now I need to change the datatype of one of the field of this trigger. One possible way is copy and paste the whole code and use ALTER command and change the existing datatype whatever I want.
But I want to ask is there any other way where without drop and recreate the trigger or alter the complete trigger code can I modify the parameters of that trigger?
There is no way in SQL Server to alter part of a Trigger. You need to rewriting the whole trigger (via ALTER TRIGGER). My best suggestion would to to use SSMS, right click on the Trigger in question and select Script Trigger as Alter. This would be the least amount of effort.
I know how to modify "CREATE PROC" templates in SSMS, and I wonder if I can modify the "ALTER PROC" template, which shows when I right-click on an existing stored procedure and click "Modify". When I click "Modify", a script "ALTER PROC ..." will be generated, I hope I can modify this so it can generate
IF EXISTS ()... DROP PROC ... CREATE PROC ...
instead of
ALTER PROC
Alternatively, if I can create a new template to achieve the same goal, that would be good too.
Thanks.
I don't think there is, but you can get pretty close to faking it. Create a snippet (in my version of SSMS, there's a Code Snippet Manager in the Tools menu) for the "if exists... drop" part. Now, script your procedure, insert your snippet at the top and you should be good to go.
I would be remiss if I didn't mention that dropping a procedure drops any explicit permissions that have been granted or denied on it. If you're doing this so that you get an idempotent script, I've adopted this idiom to avoid that problem:
if object_id('someSchema.yourProc') is not null
set noexec on;
go
create procedure someSchema.yourProc
as
print 'not yet implemented'
go
set noexec off;
go
alter procedure someSchema.yourProc as
begin
-- your actual proc
end
Yes, In modify option, you can directly modify or alter prc as
ALTER PROCEDURE [dbo].[sp_name]
#paramater INT , .... other
AS
BEGIN
.... statement
END
What the good thing in below option, is when you give to some one or deploy on server. Its good to give below type of statement.
Which first verefiy that Procedure exist or not, if exist then it first drop and then create.
IF EXISTS ()... DROP PROC ... CREATE PROC ...
Modify option means right-click and modify which directly give, alter option which is good for development purpose. You know while development like alter table or change sp parameter name. that also include when you give to someone with current sp.
While to give some one , good to drop and create with exist option, so third party easily execute without error.
I am working with SQL Server 2005 and I have trigger on a table that will copy an deletions into another table. I cannot remove this trigger completely. My problem is that we have now developed an archiving strategy for this table. I need a way of "pausing" a trigger when the stored proc that does the archiving runs.
A little more detail would be useful on how the procedure is accessing the data, but assuming you are just getting the data, then deleting it from the table and wish to disable the trigger for this process, you can do the following
DISABLE TRIGGER trg ON tbl;
then
ENABLE TRIGGER trg ON tbl;
for the duration of the procedure.
This only works for SQL 2005+
An alternative method is to use Context_Info to disable it for a single session, while allowing other sessions to continue to fire the trigger.
Context_Info is a variable which belongs to the session. Its value can be changed using SET Context_Info.
The trigger will mostly look like this:
USE AdventureWorks;
GO
-- creating the table in AdventureWorks database
IF OBJECT_ID('dbo.Table1') IS NOT NULL
DROP TABLE dbo.Table1
GO
CREATE TABLE dbo.Table1(ID INT)
GO
-- Creating a trigger
CREATE TRIGGER TR_Test ON dbo.Table1 FOR INSERT,UPDATE,DELETE
AS
DECLARE #Cinfo VARBINARY(128)
SELECT #Cinfo = Context_Info()
IF #Cinfo = 0x55555
RETURN
PRINT 'Trigger Executed'
-- Actual code goes here
-- For simplicity, I did not include any code
GO
If you want to prevent the trigger from being executed you can do the following:
SET Context_Info 0x55555
INSERT dbo.Table1 VALUES(100)
Before issuing the INSERT statement, the context info is set to a value. In the trigger, we are first checking if the value of context info is the same as the value declared. If yes, the trigger will simply return without executing its code, otherwise the trigger will fire.
source: http://www.mssqltips.com/tip.asp?tip=1591
if DISABLE TRIGGER/ENABLE TRIGGER is not an option for some reason, you can create a table with a single row which will serve as a flag for the trigger.
When I generate sql schema creation scripts manually I usually just call 'Create Procedure...', however I notice that when you generate the script using the Tasks/Generate Scripts option it uses 'spexecutesql #statement = ..' e.g.
EXEC dbo.sp_executesql #statement = N'-- =============================================
-- Author: Me
-- Create date: 20/03/2009
-- Description: Does stuff
-- =============================================
CREATE PROCEDURE [dbo].[MyProc]
-- Add the parameters for the stored procedure here
#StartDate datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
...
END
'
Why is this? Is it something about retaining comments?
Thanks
It has nothing to do with comments. It does it that way only when you tell it to "include IF NOT EXISTS". The reason is that it can only programmatically include or exclude objects if they are executed dynamically.
You can disable this is stored procedures by selecting "False" in Options\SQL Server Object Explorer\Scripting - Check for object existence.
I realize this is old, but the fix is buried pretty deep in Sql 2012. Michael Haren is right, the method of rendering sprocs changes when Object Existence Checks are required in Options. To change this, go to Options, Sql Server Object Explorer, Scripting, Object Scripting Options, and set 'Check for object existence' to false. Sprocs now render 'normally', without using sp_executesql.
sql server 2012,set Tools=>Options=>SQL Server Object Explore=>Scripting ,check object existence = false
can solve this problem.
I would guess it has to do with being able to create multiple sprocs in the same script file without GO's? If you do a create sproc ... directly, you have to complete it in a batch (finish with a GO). With the sp_executesql you shouldn't have to have a go in the generated scripts between objects. Although I don't remember, maybe there is one there anyhow.. (don't have a db in front of me).
Using spexecutesql is a best-practice. Has to do with preventing sql injection, etc. by isolating / limiting the scope of variables, etc. More here: http://msdn.microsoft.com/en-us/library/ms188001.aspx
You don't HAVE to use spexecutesql -- EXEC works too -- a lot of folks just use plain old EXEC -- it's just not as safe.
I need to alter a trigger in sql server 2005 and I want to do it using a table adapter and a sql statement, not a stored proc. I know I could run this in the query browser and execute it but I need to deploy it across several databases and use a table adapter in the update. Is this possible?
Doing Add Query -> Update -> pasting the below code -> Query Builder to see if it parses
print("USE [DataBaseName]
GO
/****** Object: Trigger [dbo].[UpdateCurrentAddress] Script Date: 10/30/2008 14:47:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[UpdateCurrentAddress] ON [dbo].[PreviousAddresses]
FOR INSERT, UPDATE, DELETE
AS
-- Check to see if there was an insert/update or a deletion.
IF (SELECT COUNT(*) FROM inserted) >= 1
BEGIN
IF (SELECT CountryID FROM inserted) <> 181
...moar...");
error...
The USE [DataBaseName] SQL construct or statement is not supported.
and if i remove the top part and start at just ALTER TRIGGER
The ALTER TRIGGER SQL construct or statement is not supported.
I'm still fairly new to this and would not be surprised that either I'm either going about this the wrong way and/or it's impossible to do without a stored proc.
EDIT: Yeah I'm doing this in C#.
thanks. I can do it that way starting at ALTER TRIGGER, this will get the job done.
The TableAdapter is expecting a resultset, not an actual query. To do this successfully you will need to use the SqlCommand object to actually peform your update.
If you have not used one before it is quite simple, first you declare your connection, then you create your command using the connection. Once the command is created set the commandtext equal to your script, and then you can call the ExecuteNonQuery() method to run the script after opening the connection. If you say what language you are using, I can try to provide an example.
Edit
Here is a C# example, quick and dirty but it gets the point across. NOTE, done from memory, but should be correct.
using(SqlConnection oConnection = new SqlConnection("Yourconnectionhere"))
using(SqlCommand oCommand = new SqlCommand(oConnection))
{
//Configure the command object
oCommand.CommandText = "Your script here";
//Open connectin and run script
oConnection.Open();
oCommand.ExecuteNonQuery();
oConnection.Close();
}