SQL Server : update table tries to drop nonexistent triggers - sql

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';

Related

Troubleshooting A Simple SQL Server Trigger

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?

Script for creating database if it doesn't exist yet in SQL Azure

This question may related to Checking if database exists or not in SQL Azure.
In SQL Azure, I tried to use a script like this to check the existence of a database, and create the database if it doesn't exist yet (in both SQLCmd and SSMS):
IF db_id('databasename') IS NULL CREATE DATABASE databasename
GO
However, SQL Azure keeps telling me
Msg 40530, Level 16, State 1, Line 2
The CREATE DATABASE statement must be the only statement in the batch.
While the same script did work on a local SQL express instance.
Does this mean it is not supported on SQL Azure?
Or is there any work around?
Thanks in advance.
Eidt:
Let me clarify what I want to achieve:
I want a script which will create a certain database only if it doesn't exist before.
Is it possible to have such kind of script for SQL Azure?
We have a similar problem.
It looks like we can do something with SET NOEXEC ON, as in the following StackExchange answer.
IF (<condition>)
SET NOEXEC ON
ELSE
SET NOEXEC OFF
GO
CREATE DATABASE databasename
GO
SET NOEXEC OFF
GO
It's saying you can't do theck and create in the same piece of sql.
i.e you need to do Select IF db_id('databasename')
test the whether it returns null, and if so then execute the create database.

Alter All Triggers via T-SQL

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...

Using table just after creating it: object does not exist

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.

SQL Studio - "Modify Stored Procedure" Script Errors

In MS SQL Server Management Studio 2005:
If you have the setting Tools|Options|Scripting|"Include IF NOT EXISTS clause" set to true, modifying a stored procedure will create a strange script that doesn't even work. It looks something like the following: (ellipsis used for brevity)
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS [...]
BEGIN
EXEC dbo.sp_executesql #statement = N'
ALTER procedure [dbo].[p_Procedure]
[...]
'
END
This obviously doesn't work because the only way the ALTER statement is called, is if the stored procedure DOESN'T exist.
The question is thus: is there any way of changing this generated code? A template out there somewhere (this doesn't seem to be related to the build in Templating tools)?
(A slight explanation for this behavior: scripting a CREATE statement generates the same code in which the IF NOT EXISTS makes more sense)
There are some issues on this topic on MS-feedback site.
Here are one:
https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=260519
Here are one comment on that issue (from the bottom of the page linked above):
In SQL2000, the approach was If
exists, DROP followed by a CREATE.
This worekd flawlessly and covered all
cases. It wored so well that we built
our deployment off of this scripting
model. Since SQl2005 entered our
world, we have had manual, cumbersome
workarounds to replace the automated
scripting that was lost in the move to
SQL2000.
Please do readd the If exists, DROP
followed by a CREATE approac. It was
great the way