2012-02-15 18 views
1

私はemtpyトリガーを作成したい、ここで奇妙な問題を抱えている:VS2010内のSQLファイルからトリガを作成しますか?

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 

私はSSMS内にこれを実行すると、それは完璧に動作しますが、私は、Visual Studio内の新しいSQLファイルを作成する場合とSQLを実行」をクリック

メッセージ2108、レベル15、状態1、プロシージャTestTrigger、 '_TestDB.dbo.test' ausgeführtのwerden、ダSICH ダスライン13 Erstellen トリガーカンのNICHTファー:」、そして、私はエラーメッセージが表示されますZiel Nicht in der Aktuellen Datenbankのプロフィール。

翻訳:

メッセージ2108、レベル15、状態1、プロシージャTestTrigger、ライン13は、 トリガを作成 ターゲットがないので、 '_TestDB.dbo.test' のために実行することができません現在のデータベースに存在します。

SSMSとVS2010は、両方とも同じユーザーと同じデータベースサーバーに接続されています。

Visual Studioでは単純なSelect * From _TestDB.dbo.testが機能するため、データベースへの接続が機能するはずです。しかし、なぜそれは作成トリガーのために働いていないのですか?

答えて

3

エラーが示すように、トリガーは元のターゲット表と同じデータベースに作成する必要があります。だから、

あなたdbo.testテーブル

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 

編集と同じDB(_TestDB)でトリガを作成することを確認してください。ただ、明確にする - 接続はデータベースで、サーバーインスタンスレベルではなく、レベル。テーブルを_TestDB.dbo.testとすると、現在のデータベース(カタログ)が現在別のデータベースを指している場合でもテーブルにアクセスできます。

:OIC - はい、現在のデータベースが "_TestDB"ではないことを意味します。また、SQLのDDL実行に矛盾があります。ほとんどのDDLコマンドは、リモートデータベース(CREATE INDEXを含む)から正常に実行できますが、何らかの理由でトリガーではありません。以下は、不一致を強調する(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 
+0

ありがとう、それは動作します。しかし、なぜ私は理解していない。私は "ON _TestDB.dbo.test"と思ったのですが、私はすでに使用するデータベースを教えてくれましたか? – Feroc

+0

トリガをイベントの「リスナ」/サブスクライバとみなします。トリガは、リスンしているアクションの「サブジェクト」(テーブルdbo.Testの更新)と同じdb内になければなりません。ただし、 'ローカル'トリガーを使用して別のデータベースの表にデータを挿入することはできます。 – StuartLC

+0

私は技術的に違いがないとは認めなければなりませんが、とにかく大きなSQL-guyではありません。常に、 "USE _TestDB"は、このスクリプトに使用するデータベースを教えてくれますが、 "Create ... ON _TestDB.dbo.test"は、トリガーが_TestDBにあることを通知する必要があります。しかし、私のバージョンがSSMSで動作していない(スクリプトを編集している間にドロップダウンリスト内のデータベースを変更しても)、私はこのようにデータベースを指すことはできないと受け入れなければならないと思う。再度、感謝します。 :) – Feroc

関連する問題