1

I have a strange problem here, I want to create an emtpy trigger:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER dbo.TestTrigger 
   ON  _TestDB.dbo.test
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;
END
GO

If I execute this within SSMS it works perfectly, but if I create a new SQL file within Visual Studio and click "Execute SQL", then I just get an error message:

Msg 2108, Level 15, State 1, Procedure TestTrigger, Line 13 Erstellen Trigger kann nicht für '_TestDB.dbo.test' ausgeführt werden, da sich das Ziel nicht in der aktuellen Datenbank befindet.

Translation:

Msg 2108, Level 15, State 1, Procedure TestTrigger, Line 13 Create Trigger cannot be executed for '_TestDB.dbo.test', because the target doesn't exist in the current database.

SSMS and VS2010 are both connected to the same databaseserver as the same user.

A simple Select * From _TestDB.dbo.test does work within Visual Studio, so the connection to the database should work. But why is it not working for Create Trigger?

1 Answer 1

3

As the error implies, triggers must be created in the same database as the underlying target table.

So ensure that you create the trigger in the same DB (_TestDB) as your dbo.test table

USE _TestDB
GO

SET ANSI_NULLS ON GO 
SET QUOTED_IDENTIFIER ON 
GO  

CREATE TRIGGER dbo.TestTrigger     
ON  dbo.test    
AFTER UPDATE AS  
BEGIN     
  SET NOCOUNT ON; 
END 
GO 

Edit : Just to clarify - a connection is at server instance level, not at database level. By qualifying your table as _TestDB.dbo.test you will be able to access the table even if your current database (catalogue) is currently pointing to a different database.

Edit : OIC - yes, it means that your current db isn't "_TestDB". You've also picked up an inconsistency in SQL's DDL execution. Most of the DDL commands can be successfully executed from a remote database (Including CREATE INDEX), but for some reason, not a trigger. The following highlights the inconsistency (SQL 2008 Express)

use master
go

CREATE DATABASE bob
GO

-- DB_NAME() = master
CREATE TABLE bob.dbo.SomeTable
(
    SomeTableId INT NOT NULL,
    AnotherField VARCHAR(50) NULL
)
GO -- Success

-- DB_NAME() = master
CREATE INDEX IX1_SomeTable on bob.dbo.SomeTable(SomeTableId)
GO -- Success. Note that the index is actually created in bob, not master of course

-- DB_NAME() = master
ALTER TABLE bob.dbo.SomeTable ADD CONSTRAINT PK_SomeTableId PRIMARY KEY(SomeTableId)
GO -- Success

-- DB_NAME() = master
CREATE TRIGGER bob.dbo.SomeTableTrigger -- 'CREATE/ALTER TRIGGER' does not allow specifying the database name as a prefix to the object name.
    ON  bob.dbo.SomeTable
    AFTER UPDATE
AS
    BEGIN
        PRINT 'Trigger called'
    END
GO

-- DB_NAME() = master - this is your scenario - 
CREATE TRIGGER dbo.SomeTableTrigger -- Cannot create trigger on 'bob.dbo.SomeTable' as the target is not in the current database.
    ON  bob.dbo.SomeTable
    AFTER UPDATE
AS
    BEGIN
        PRINT 'Trigger called'
    END
GO

USE BOB
GO

-- DB_NAME() = bob
CREATE TRIGGER dbo.SomeTableTrigger -- Success
    ON  bob.dbo.SomeTable
    AFTER UPDATE
AS
    BEGIN
        PRINT 'Trigger called'
    END
GO
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, that works. But I don't understand why. I thought with "ON _TestDB.dbo.test" I already tell him which database to use?
Think of a trigger as a 'listener' / subscriber to an event - it must be in the same db as the 'subject' to the action for which it is listening (viz updates on table dbo.Test). You can still use the 'local' trigger to insert data into a table in another database however.
I must admit, that I don't get the difference technically, but I am not a big SQL-guy anyway. Always thought, that "USE _TestDB" tells him which database to use for this script, while "Create ... ON _TestDB.dbo.test" should tell him, that the trigger is in the _TestDB. But as my version is not working in SSMS either (if I change the database in the dropdown while editing the script), I guess I just have to accept, that I can't point to the database this way. Thanks again. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.