1

特定のフィールドが (単一行または複数行の更新から) NULL に設定されているかどうかをチェックするトリガーを作成し、そうであれば、そのフィールドを初期値に戻すことは可能ですか?

サイトを検索しましたが、私の正確な要件に一致するものは見つかりませんでした。

背景のビット:

2 つのアプリケーション (時間管理 Web アプリと Microsoft プロジェクト サーバー) があり、組織内のリソースに関する更新情報を相互に送信しています。いずれかのシステムで変更が行われると、その更新がもう一方のシステムに送信されます。ただし、時間管理 Web アプリ (テーブル名) にのみ存在する特定のフィールドがありresource、MSP サーバーはこれらのフィールド (フィールド名GLMaskingValue)の 1 つを強制的NULLに更新し、一部の更新を行います (私が知る限り、すべてではありません)。 .

私はコードにアクセスできず、Web アプリケーション データベースだけにアクセスできません。また、update ステートメント全体を失敗させたくありません (これは、テーブルの制約を使用して行うことができます)。誰かがそれを に変更しようとした場合NULL

私はトリガーのルートをたどっていますが、これを行うにはもっと良い方法があるかもしれません-もしそうなら、私に教えてください!

4

3 に答える 3

4

このようなもの:

CREATE TRIGGER trig_test
ON dbo.t
AFTER update
AS
update t
set t.x = d.x
from t as t
join deleted d 
on t.id = d.id -- use the primary key of the table instead of id
where t.x is null
于 2012-09-17T11:40:03.317 に答える
3

唯一の更新が問題である場合、はい、「更新の代わりに」トリガーを使用してそれを強制できます。注意点は、変更を適用するために更新ステートメントを作成する必要があることです。

create table data (id int not null, name varchar(50), postcode varchar(50), sex bit, primary key(id))
go
create trigger tg_data_before on data instead of update as 
begin
  set nocount on
  update data 
    set name = coalesce(c.name, b.name),
      postcode = coalesce(c.postcode, b.postcode),
      sex = coalesce(c.sex, b.sex)
  from data a
  join deleted b on a.id = b.id
  join inserted c on a.id = c.id
end
go

insert data values (1, 'sven', '1234', 0)
insert data values (2, 'lars', '2345', 0)
insert data values (3, 'foo', '3456', 1)

update data set name = null
update data set postcode = null where id = 1
update data set postcode = 'zoink' where id in (2,3)
update data set sex = 1-sex

select * from data

drop table data

しかし、「not null」を使用してクライアントコードを修正する方が良いと思います.マージ):

create table data (id int not null, name varchar(50) not null, postcode varchar(50) not null, sex bit not null, primary key(id))
于 2012-09-17T12:04:21.537 に答える
0

コードが修正されるまでは、良い計画のように思えます。これは、複数行、複数列のトリガーです。ここでの利点は、2 つの列の一方または両方が変更された場合にのみ更新を実行することです。また、以前の値が null ではない行/列にのみ作用することにも注意してください。

CREATE TRIGGER tr_resource_nullcheck ON resource
FOR UPDATE
AS
SET NOCOUNT ON
IF (UPDATE(GLMaskingValue) OR UPDATE(Column2))
BEGIN
  update r
    set r.GLMaskingValue = isnull(r.GLMaskingValue, d.GLMaskingValue)
        r.column2 = isnull(r.column2, d.column2)

  from resource r
  join deleted d on d.resourceId = r.resourceId
  where (r.GLMaskingValue is null and d.GLMaskingValue is not null) 
  or (r.column2 is null and d.column2 is not null)
END
于 2012-09-17T12:05:03.150 に答える