【问题标题】:Update / Insert trigger in SQL ServerSQL Server 中的更新/插入触发器
【发布时间】:2012-06-12 15:39:54
【问题描述】:

我是 SQL Server 和触发器的新手。我想创建一个在插入新行或更新现有行时触发的触发器。触发器将更新一组计算列。

谁能给我一个基本的触发器来检查fldType = 'INVALID',如果是,它将另一列errInvalid设置为1

请记住,每天将插入 5000 行(一次点击),因此性能是一个问题。我在其他地方看过,但只是感到困惑。

好的,我的问题已经演变。我已经沿着 Persisted Colums 路线行驶。我已经创建了一个成功的基本持久字段,但是在嵌套逻辑 pf 方面遇到了问题。

我可以(以及如何)执行以下操作:

案例 当 [MissCustName] 为真时 当 [CustomerAccountName] 为 NULL 时 (1) 别的 (0) 结尾 别的 (0) 结束

【问题讨论】:

  • 我认为您对“计算列”是什么感到困惑。如果它在计算列的位置,那么您不需要更新它,它将是自动的,不需要触发器。实际上,这似乎是您的最佳选择
  • 你有没有尝试过?如果是,请在此处发布。
  • 我可以想象有人在 20 年后打开 SO 的档案,然后“在 2012 年每天将 5000 行插入数据库是一个严重的问题”;-)

标签: sql-server sql-server-2008 tsql


【解决方案1】:

也许更好的选择是改用计算列..

create table myTab
(
    fieldType varchar(10),
    errInvalid As Case When fieldType = 'INVALID' then 1 else 0 end PERSISTED
)
Go
insert into mytab(fieldType) values ('aaa')
insert into mytab(fieldType) values ('INVALID')
Go
Select * from mytab

【讨论】:

  • 我确实考虑过计算字段,但有些我需要执行某种查找,我不想影响性能,所以认为最好有只更改的静态字段当我更新或插入?
  • “PERSISTED”关键字正是您所需要的。如果它的“Persisted” - 它在插入/更新时计算。
  • 好的,我的问题已经演变。我已经沿着 Persisted Columns 路线行驶。我已经创建了一个成功的基本持久字段,但是在嵌套逻辑 pf 方面遇到了麻烦。我可以(以及如何)执行以下操作:当 [MissCustName] 为 true 时,当 [CustomerAccountName] 为 NULL 时,然后 (1) else (0) end else (0) end
  • Case When fieldType = 'INVALID' then 1 else Case When otherField = 'value' then 2 else 0 end end /// 就像任何 case 语句一样..
  • GRRRR,认为它在引用另一个持久字段时遇到了问题。它是否按顺序计算持久化字段?
【解决方案2】:

你可以使用类似这样的东西:

CREATE TRIGGER dbo.trgInsertUpdate
ON dbo.YourTableNameHere
FOR INSERT, UPDATE 
AS BEGIN
   -- update the column
   UPDATE dbo.YourTableNameHere
   SET errInvalid = 1
   FROM Inserted i 
   WHERE 
      dbo.YourTableNameHere.ID = i.ID   -- establish link to "Inserted" pseudo-table
      AND fldType = 'INVALID'
END

基本上,每个语句都会调用一次触发器一次,因此它可能一次应用于多行。这些行及其新值存储在Inserted 伪表中,该表包含表中的所有列。

您需要在表中找到fldType = 'INVALID' 所在的行,这些行也是Inserted 伪表的一部分(已插入或更新)。

【讨论】:

  • @Bridge:是的 - 抱歉 - 打字太快 :-) 谢谢!已更新。
  • +1 我会假装我也没有注意到其他 3 个编辑。慢下来;-)
【解决方案3】:

我认为这会做你想要的:

CREATE TRIGGER Trigger1
ON Table1
FOR INSERT, UPDATE
AS
    UPDATE t
    SET    errInvalid = 1
    FROM   Table1 t
           INNER JOIN Inserted i
             ON i.id = t.id
    WHERE  t.fldType = 'INVALID'

【讨论】:

    【解决方案4】:

    您确实需要一个计算列。它会表现得更好。请参阅this SO 帖子。

    CREATE TABLE [dbo].[myTab]
    (
      [fldType] [varchar](50) NULL ,
      [errInvalid] AS ( CASE [fldType]
                          WHEN 'Invalid' THEN ( 1 )
                          ELSE ( 0 )
                        END )
    ) 
    

    【讨论】:

      【解决方案5】:

      为什么不使用“真正的”计算列?

      例如:

      CREATE TABLE foobar
      (
          fldType varchar(10),
          errInvalid AS CASE WHEN fldType = 'INVALID' THEN 1 ELSE 0 END
      )
      

      如果您进行大量读取(几乎达到“物理”列的级别),使用持久计算列可能会提高性能。只需在列定义后添加PERSISTED

      CREATE TABLE foobar
      (
          fldType varchar(10),
          errInvalid AS CASE WHEN fldType = 'INVALID' THEN 1 ELSE 0 END PERSISTED
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多