web-dev-qa-db-ja.com

SQL Server AFTER INSERTトリガー

marital_status列にテキストmarriedを挿入した後、このトリガーを起動したいのですが、これが今のところ

ALTER TRIGGER [dbo].[marriage]
ON  [dbo].[applicant_personal_info]
AFTER INSERT
AS 
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
IF (SELECT [marital_status] FROM inserted) = 'married'
 BEGIN
     INSERT INTO [dbo].[applicant_marriage_info]([dom])
     VALUES('abc')
 END
END
10
kabuto178

ここで遭遇する問題は、SQL ServerにはOracleのような「FOR EACH ROW」トリガーがないという事実から来ています。複数行の変更を処理するためにトリガーを作成する必要があります。つまり、INSERTEDまたはDELETED仮想テーブルには複数の行を含めることができます。

そのような更新が行われた場合、(SELECT [marital_status] FROM inserted)は複数の行を返し、サブクエリは直接比較で使用される単一の値を返す必要があるため、トリガーは失敗します。

トリガーはおそらく次のようになります。

CREATE TRIGGER [dbo].[marriage] ON  [dbo].[applicant_personal_info] FOR INSERT
AS 
BEGIN
    SET NOCOUNT ON
    IF EXISTS (SELECT [marital_status] FROM INSERTED WHERE marital_status = 'married')
    BEGIN
        INSERT INTO [dbo].[applicant_marriage_info] ([dom])
        SELECT
            'abc' --Replace with whatever you're really inserting
        FROM INSERTED
        WHERE marital_status = 'married'
    END
END
11
db2

したがって、このトリガーは実際には必要なものにかなり近いです。ここで問題となるのは、挿入された行がある場合に1行だけがapplied_marriage_infoに挿入されることです。これはあなたが実際に欲しいものですか?一度に複数の行が挿入された場合はどうなりますか?

ALTER TRIGGER [dbo].[marriage]
ON  [dbo].[applicant_personal_info]
AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    INSERT INTO [dbo].[applicant_marriage_info]([dom])
    SELECT 'abc' 
    FROM inserted 
    WHERE marital_status = 'married'
END

おそらく、これまでに示したよりも多くの列が必要になります。

8
mrdenny