7

質問:
SQL-Server 2005データベースには、テーブルT_Groupsがあります。
T_Groupsには、とりわけ、フィールドID(PK)と名前があります。

今、私たちの会社の何人かの馬鹿は、マッピングテーブルのキーとして名前を使用しました...
つまり、グループ名を変更することはできません。変更すると、マッピングが失われるためです...
これが解決されるまで、私は必要ですT_Groupsに制限を追加して、グループの名前を更新できないようにします。
挿入は引き続き可能であり、グループ名を変更しない更新も可能であることに注意してください。

また、アプリケーションのユーザーと開発者はdboとsysadminの両方の権限を持っているため、REVOKE/DENYは機能しないことに注意してください。

トリガーを使用してこれを行うにはどうすればよいですか?

4

4 に答える 4

15
CREATE TRIGGER dbo.yournametrigger ON T_Groups
FOR UPDATE
AS
BEGIN
  IF UPDATE(name)
  BEGIN
    ROLLBACK
    RAISERROR('Changes column name not allowed', 16, 1);
  END
  ELSE
  BEGIN
  --possible update that doesn't change the groupname
  END
END
于 2012-10-26T07:41:39.560 に答える
8
CREATE TRIGGER tg_name_me
ON tbl_name
INSTEAD OF UPDATE
AS
IF EXISTS (
   SELECT *
   FROM INSERTED I
   JOIN DELETED D ON D.PK = I.PK AND ISNULL(D.name,I.name+'.') <> ISNULL(I.name,D.name+'.')
)
RAISERROR('Changes to the name in table tbl_name are NOT allowed', 16,1);
GO

データベースにアクセスするためのアプリケーションフレームワークによっては、変更をチェックするためのより安価な方法がAlexanderの答えです。一部のフレームワークは、変更されていない場合でもすべての列を含むSQL更新ステートメントを生成します。

UPDATE TBL
   SET name = 'abc', -- unchanged
       col2 = null, -- changed
       ... etc all columns

この関数は、値が変更されたかどうかではなく、列がステートメントに存在UPDATE()するかどうかをチェックするだけです。この特定のステートメントは、を使用してエラーを発生させますが、上記のように、より複雑なトリガーを使用してテストした場合は発生しません。UPDATE()

于 2012-10-26T07:33:07.453 に答える
0

これは、更新トリガーを使用して元の値を保持する例です。これは、orig_authorとorig_dateの値を、削除された疑似テーブルの値に毎回設定することで機能します。それでも作業を実行し、サイクルを使用します。

CREATE TRIGGER [dbo].[tru_my_table]  ON [dbo].[be_my_table]
AFTER UPDATE
AS
    UPDATE [dbo].[be_my_table]
    SET
    orig_author = deleted.orig_author
    orig_date   = deleted.orig_date,
    last_mod_by = SUSER_SNAME(),
    last_mod_dt = getdate()
    from deleted
    WHERE deleted.my_table_id IN  (SELECT DISTINCT my_table_id FROM Inserted)

ALTER TABLE [dbo].[be_my_table] ENABLE TRIGGER [tru_my_table]
GO
于 2021-04-08T06:06:01.497 に答える
0

この例では、トリガーを介してSABENTIS_LOCATION.fk_sabentis_locationの更新をロックし、影響を受けるオブジェクトを示す詳細なメッセージを出力します。

ALTER TRIGGER dbo.SABENTIS_LOCATION_update_fk_sabentis_location ON SABENTIS_LOCATION
FOR UPDATE
AS
DECLARE @affected nvarchar(max)
SELECT @affected=STRING_AGG(convert(nvarchar(50), a.id), ', ')
  FROM inserted a
  JOIN deleted b ON a.id = b.id
  WHERE a.fk_sabentis_location != b.fk_sabentis_location
IF @affected != ''
BEGIN
  ROLLBACK TRAN
  DECLARE @message nvarchar(max) = CONCAT('Update values on column fk_sabentis_location locked by custom trigger. Could not update entities: ', @affected);
  RAISERROR(@message, 16, 1)
END

いくつかの例が使用しているようです:

IF UPDATE(name)

ただし、値自体が変更されていないために誤検知が発生した場合でも、フィールドが更新ステートメントの一部である場合、これはTRUEと評価されるようです。

于 2021-10-28T07:51:20.543 に答える