I'm using SQL Server 2008 here. I inherited an old web app that is dying, and being replaced by a totally new web app. The new project is up and running but the old one will exist for the next month and a half for the transition period.
Here's the problem: action needs to be taken when someone adds a new record to a table in SQL Server using this app. The old source code is pretty hosed (seriously, no version control before my arrival) and I can't afford to take the time to hobble something together just so I can get an email notification using the old app.
My thought - use a SQL Server trigger to send an email AFTER INSERT. Really this is all I want: whenever a new record (and it's always one, not dozens) is entered into a table, I want to send myself and another lucky person an email. I've never done this in SQL Server but it seems doable.
Here's my SQL script as it currently stands:
CREATE TRIGGER NotificationMail
ON OldJunk.[dbo].[JunkTable]
AFTER INSERT
AS
BEGIN
EXEC msdb.dbo.sp_send_dbmail --QUESTION: I HAVE NO IDEA WHAT TO PUT HERE, WHAT FOLLOWS
-- IS JUST COPYPASTA FROM A FORUM
#recipients = 'shubniggurath#email.com, someoneelse#email.com',
#subject = 'Old Registration Request - New Record',
#body = 'Somebody decided to register using the old system.'
END
GO
I'm getting this error when I try to execute this create statement:
Cannot create trigger on 'OldJunk.dbo.JunkTable' as the target is not in the current database.
Thanks in advance for your help.
You have to be in the OldJunk database (by using the USE .... command in SQL Server Management Studio), and then create the trigger using these SQL statements:
USE OldJunk;
GO
CREATE TRIGGER NotificationMail ON [dbo].[JunkTable]
.....
You cannot use the three-part (database).(schema).(object) notation in the trigger definition.
If that doesn't work - then you probably don't have such a table - is there a typo? Or is this not really a table?
Related
I am using Microsoft SQL Server 2008 R2 (SP2). I am not using SQL Server Management Studio. I am using a simple webpage with a textarea for a query window that I built myself in PHP, so all I am doing are SQL commands -- no GUI stuff. Never had problems with it before, and I don't think the problems I'm having now are because of my PHP. Anyway, I would most appreciate answers in SQL code rather than answers that recommend I right-click the table name in Management Studio, if you get my drift.
Leading up to the problem...
I used to have three triggers on table dbo.MyOldTableName:
trgOldUpdate1, trgOldUpdate2, and trgOldInsert
I renamed the table using the following code:
EXEC sp_rename 'dbo.MyOldTableName', 'MyNewTableName';
I then dropped those three old triggers and created the following three new triggers (which do the same thing but point to the new table and have new names):
trgNewUpdate1, trgNewUpdate2, and trgNewInsert
I ran this SQL and saw only the new triggers:
SELECT
referencing_schema_name,
referencing_entity_name,
referencing_id,
referencing_class_desc,
is_caller_dependent
FROM
sys.dm_sql_referencing_entities ('dbo.MyOldTableName', 'OBJECT');
I ran this SQL and the old triggers are not there:
SELECT * FROM sys.triggers;
Now all of that above information is simply background. Here is the actual problem. I ran a simple update command (like this SQL):
UPDATE [dbo].[MyNewTableName] SET ColumnName = ColumnName;
...and got these error messages:
Cannot drop the trigger 'dbo.trgOldUpdate2', because it does not exist or you do not have permission.
Cannot drop the trigger 'dbo.trgOldUpdate1', because it does not exist or you do not have permission.
Cannot drop the trigger 'dbo.trgOldUpdate1', because it does not exist or you do not have permission.
Cannot drop the trigger 'dbo.trgOldUpdate2', because it does not exist or you do not have permission.
First, why is SQL Server trying to drop triggers on a simple update command (And before you ask, no, the trigger code itself never drops anything at all)?
Second, why is SQL Server looking for triggers that don't exist?
Third and most important, how do I stop this from happening?
Many thanks in advance for your clear, concise, and self-contained answers! (Hey, a guy can dream, can't he?)
My guess is that there was an error in the trigger DROP/CREATE script such that the DROP statements of the old triggers were inadvertently included in in one of the update triggers. Check the new triggers to see if that is the case:
EXEC sp_helptext N'trgNewUpdate1';
EXEC sp_helptext N'trgNewUpdate2';
Is there a way to update/alter all triggers using Looping T-SQL or a C# Code ?. I need it too update all the triggers in my database because the RAISERROR command has changed in sql server 2012.
You can script out all the triggers into a text file. See:
How to Generate Scripts For All Triggers in Database Using Microsoft SQL Server Management Studio
Then, you can use a text editor to replace the code you need to replace. Then, you can drop your triggers and recreate them. I don't know if your referring to a production database, or one that you are doing development on. I am assuming from your question that you are prepared to make these major changes to your database. Make sure you back up your database first, in any event.
You can get all trigger using
SELECT [name] FROM [sys].[triggers]
and loop through each trigger and execute
EXEC sp_helptext 'TriggerName'
so you will have the create statement with it...
SQL Server 2005, Win7, VS2008. I have to upgrade database from the old version of product to the newer one. I'd like to have one script that creates new database and upgrades old database to the new state. I am trying to do the following (SQL script below) and get the error (when running on machine with no database ):
Database 'MyDatabase' does not exist. Make sure that the name is
entered correctly.
The question is:
How can I specify database name in upgrade part
Is the better way to write create/upgrade exists ?
SQL code:
USE [master]
-- DB upgrade part
if exists (select name from sysdatabases where name = 'MyDatabase')
BEGIN
IF (<Some checks that DB is new>)
BEGIN
raiserror('MyDatabase database already exists and no upgrade required', 20, -1) with log
END
ELSE
BEGIN
USE [MyDatabase]
-- create some new tables
-- alter existing tables
raiserror('MyDatabase database upgraded successfully', 20, -1) with log
END
END
-- DB creating part
CREATE DATABASE [MyDatabase];
-- create new tables
You don't usually want to explicitly specify database name in a script. Rather, supply it exernally or pre-process the SQL to replace a $$DATABASENAME$$ token with the name of an actual database.
You're not going to be able to include the USE [MyDatabase] in your script since, if the database doesn't exist, the query won't parse.
Instead, what you can do is keep 2 separate scripts, one for an upgrade and one for a new database. Then you can call the scripts within the IF branches through xp_cmdshell and dynamic SQL. The following link has some examples that you can follow:
http://abhijitmore.wordpress.com/2011/06/21/how-to-execute-sql-using-t-sql/
PowerShell may make this task easier as well, but I don't have any direct experience using it.
I have a database view that gathers about 10 member names a day, based on when they joined.
I want to setup something where these people will automatically be emailed an html page
i have made.
and repeat this daily, at first i was going to build an asp.net page
where i would pull the view and loop through the email addresses, but i wanted to see if it was possible to do this soley in sql server 2005
Could i use a trigger or a stored procedure or i havent really used sql server agent
sp_send_dbmail as the others said is what you use to send the E-mail
To set it up to E-mail daily you can use a SQL Server Agent Job
In SSMS, connect to your server, then open SQL Server Agen->Jobs
In here you can set up the steps for your job and the frequency with which it runs.
You can use sp_send_dbmail to send email directly from SQL Server, assuming you've set up Database Mail.
You could use an INSERT trigger and send them an email on the spot as soon as they join.
See: sp_send_dbmail at http://msdn.microsoft.com/en-us/library/ms190307.aspx
Trigger example: http://www.codeproject.com/KB/database/TriggersSqlServer.aspx
I have a script in T-SQL that goes like this:
create table TableName (...)
SET IDENTITY INSERT TableName ON
And on second line I get error:
Cannot find the object "TableName" because it does not exist or you do not have permissions.
I execute it from Management Studio 2005. When I put "GO" between these two lines, it's working. But what I would like to acomplish is not to use "GO" because I would like to place this code in my application when it will be finished.
So my question is how to make this work without using "GO" so that I can run it programmatically from my C# application.
Without using GO, programmatically, you would need to make 2 separate database calls.
Run the two scripts one after the other - using two calls from your application.
You should only run the second once the first has successfully run anyway, so you could run the first script and on success run the second script. The table has to have been created before you can use it, which is why you need the GO in management studio.
From the BOL: "SQL Server utilities interpret GO as a signal that they should send the current batch of Transact-SQL statements to SQL Server". Therefore, as Jose Basilio already pointed out, you have to make separate database calls.
If this can help, I was faced with the same problem and I had to write a little (very basic) parser to split every single script in a bunch of mini-script which are sent - one at a time - to the database.
something even better than tpdi's temp table is a variable table. they run lightning fast and are dropped automatically once out of scope.
this is how you make one
declare #TableName table (ColumnName int, ColumnName2 nvarchar(50))
then to insert you just do this
insert into #TableName (ColumnName, ColumnName2)
select 1, 'A'
Consider writing a stored proc that creates a temporary table and does whatever it needs to with that. If you create a real table, your app won't be able to run the script more than once, unless it also drops the table -- in which case, you have exactly the functionality of a temp table.