Lost trigger in SQL Server - sql

I have lost a trigger. I know it is active, since when I try to change a field, it restores its value back, and from the SQL Server Management Studio I can see that when I execute the query, an extra one is executing (the trigger one).
I tried SELECT * FROM sys.triggers WHERE 1 = 1 but it does not return anything. Also, I know the name of the trigger, but when I try to ALTERit returns an error saying that
the name of the object 'myTrigger' is not valid.
And if I try to DROP TRIGGER myTrigger ON DATABASE
Trigger 'myTrigger' can not be removed because it does not exists, or the user has not enough priviledges.

Ok, as Lieven said, I was not querying the right database... This is odd, since the query had the DB defined on it
ALTER TRIGGER myTrigger
ON [DB].[dbo].[table]
But the upper select of the SQL Server Management Studio was pointing to other DB...
Edit:
I have been investigating a little bit (trying to clean my image), and I found a weird behaviour on SQL Server Management Studio.
If you execute a query like:
UPDATE [DB].[dbo].[table] SET column = 'value' WHERE column2 = 'foo'
It executes the query in the right DB. No matter what DB is pointed by the upper select.
But, if you try to do the same, with a trigger, you must have the upper select pointing the right DB, or you will face the same problems I had.

I had a subtle error kind of like yours; I did something like this:
CREATE TRIGGER [TrigCustomerInsertDelete]
ON [mobile].[Customers]
AFTER INSERT, DELETE
AS
select 'I' [ACTION],* from inserted
select 'D' [ACTION],* from deleted
GO
and then later tried to update it with:
ALTER TRIGGER [TrigCustomerInsertDelete]
and got this error: Invalid object name
The problem was that I did not specify the schema on the trigger (thinking it would just be dbo), but the table does have a schema. So, I figured out the error after including the schema on the trigger.
CREATE TRIGGER [DBO].[TrigCustomerInsertDelete]
This gave me the following error: Cannot create trigger 'DBO.TrigCustomerInsertDelete' because its schema is different from the schema of the target table or view.
I know this is an old post, but hopefully it will help someone else.

Related

SQL - Table not found after backup

I saved a SQL table before deleting some information from it with the sql statment:
select * into x_table from y_table
After doing some operations, I want to get back some information from the table I saved with the query above. Unfortunately, MS SQL Server MGMTS shows an error saying that the table does not exist.
However, when I put the drop statement, the table is recognized - and the table is not underlined.
Any idea why this table is recognized by the drop table statement and not the select from statement. This seems strange for me.
EDIT:
Thank you
It may be that the table isn't underlined in your drop table command because its name is still in your IntelliSense cache. Select Edit -> IntelliSense -> Refresh Local Cache in SSMS (or just press Ctrl+Shift+R) and see if the table name is underlined then.
Edit:
Another possibility is that your drop table command might be in the same batch as another statement that creates the table, in which case SSMS won't underline it because it knows that even though the table doesn't exist now, it will exist by the time that command is executed. For instance:
None of the tables one, two, or three existed in my database when I took this screenshot. If I highlight line 6 and try to run it by itself, it will fail. Yet you can see that two is not underlined on line 6 because SSMS can see that if I run the whole script, the table will be created on line 5. On the other hand, three is underlined on line 9 because I commented out the code that would have created it on line 8.
All of that said, I think we might be making too much of this problem. If you try to select from a table and SQL Server tells you it doesn't exist, then it doesn't exist. You can't rely on IntelliSense to tell you that it does; the two examples above are probably not the only ways that IntelliSense might mislead you about the current status of a table.
If you want the simplest way to know whether an object with a given name (like x_table) exists, just use:
select object_id('x_table');
If this query returns null, x_table doesn't exist, regardless of what IntelliSense is telling you. If it returns non-null, then there is some object out there with that name, and then the real question is why your select statement is failing. And to answer that, I'd need to see the statement.
A lot of posts like this, you have to copy in 2 statements :
CREATE TABLE newtable LIKE oldtable;
INSERT newtable SELECT * FROM oldtable;

Access 10' with SQL Server DB 'Operation must use an updateable query'

I have an Access 2010 'front-end' DB that has its data stored in a SQL Server DB 'back-end.'I'm trying to write the most simple UPDATE query I can and being met with this error: 'Operation must use an updateable query.' My qry code is:
UPDATE tblTableLastModifiedDates SET LastModified = NOW()
WHERE id='1';
A lot of this DB was set up before I got this job so the dumb table names are not my fault. Also, I checked the tblTableLastModifiedDates and it actually has no PK and I've been unable to create one. I'm not sure if that is the problem.
Before I scrap all this and start it over (to do it the right way), I figured I'd ask if anyone knew how to fix this error.
This error implies that tblTableLastModifiedDates is a view that is not unique enough to update the LastModified field in the underlying table. This isn't that uncommon.
The best approach is going to be to execute the UPDATE against the underlying table.

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.

Watch a Database column to determine what is modifying

How do I find out what application or SP is modifing the values in a config table? I thought I had isolated the app that was responsible but these particular values keep chnging back to true when I keep modifying them to be false.
First, create a logging table:
CREATE TABLE modlog(
datestamp smalldatetime,
username varchar(255) NOT NULL DEFAULT SYSTEM_USER
);
Then create an UPDATE trigger on your table:
CREATE TRIGGER mytable_mods ON mytable FOR UPDATE AS
INSERT INTO modlog(smalldatetime) VALUES (GETDATE());
Just peek into the modlog table to figure out which user is updating the table, and when. You could get fancy and also log particular fields being updated.
Another approach would be to set up a trace in SQL Server Profiler, filter the heck out of it so it only returns updates on that table, and keep it open until something happens.
If your applications include the ApplicationName parameter in their connection strings, you can use App_Name() instead of SYSTEM_USER, which will log the application name, removing the extra detective work. Knowing the user might still be useful so you can figure out what they are doing to trigger the update.
Create a trigger to roll back the update. Wait for the app to error out. It can be a very simple trigger:
CREATE TRIGGER BugOffRogueProgram
ON MyConfigTable
FOR UPDATE
AS
BEGIN
ROLLBACK TRAN
END
The answers provided so far are absolutely on the spot - that's the way to do it in SQL Server 2005.
Just as a brief teaser: in SQL Server 2008, there's a new feature called Change Data Capture to support this exact scenario "out of the box" without the need to write triggers and update tables yourself. Quite handy!
Marc

Force SQL Server column to a specific value

Is it possible to force a column in a SQL Server 2005 table to a certain value regardless of the value used in an insert or update statement is? Basically, there is a bug in an application that I don't have access to that is trying to insert a date of 1/1/0001 into a datetime column. This is producing a SqlDateTime overflow exception. Since this column isn't even used for anything, I'd like to somehow update the constraints on the columns or something in the database to avoid the error. This is obviously just a temporary emergency patch to avoid the problem... Ideas welcome...
How is the value being inserted? If it's through a stored proc... you could just modify the Sproc to ignore that input parameter.
if it's through client-side generated SQL, or an ORM tool, otoh, then afaik, the only option is a "Before" Trigger that "replaces" the value with an acceptable one...
If you're using SQL 2005 you can create an INSTEAD OF trigger.
The code in this trigger wil run in stead of the original insert/update
-Edoode
I'd create a trigger to check and change the value
If it is a third party application then I will assume you don't have access to the Stored Procedure, or logic used to generate and insert that value (it is still worth checking the SPs for the application's database though, to see if you can modify them).
As Charles suggested, if you don't have access to the source, then you need to have a trigger on the insert.
The Microsoft article here will give you some in depth information on creating triggers.
However, SQL Server doesn't have a true 'before insert' trigger (to my knowledge), so you need to try INSTEAD OF. Have a look here for more information. In that article, pay particular note of section 37.7, and the following example (again from that article):
CREATE TRIGGER T_InsertInventory ON CurrentInventory
INSTEAD OF INSERT AS
BEGIN
INSERT INTO Inventory (PartNumber, Description, QtyOnOrder, QtyInStock)
SELECT PartNumber, Description, QtyOnOrder, QtyInStock
FROM inserted
END
Nick.
the simplest hack would be to make it a varchar, and let it insert that as a string into the column.
The more complicated answer is, you can massage the data with a trigger, but it would still have to be valid in the first place. For instance I can reset a fields value in an update/insert trigger, but it would still have to get through the insert first.