【问题标题】:SQL Server trigger to replace "false" with nullSQL Server 触发器将“false”替换为 null
【发布时间】:2018-06-22 00:57:58
【问题描述】:

我在 SQL Server 2017 数据库中有一个包含 2 个 numeric 列和 3 个 varchar 列的表。我想要一个触发器来检查每个插入/更新的行,并且当任何varchar 列包含文本“false”时,将其替换为NULL

没有主键列,每列都可以为空,所以我无法加入“插入”的伪表。

我更熟悉 Oracle,其中的逻辑可能类似于:

BEFORE INSERT OR UPDATE ON table1
FOR EACH ROW
BEGIN
  IF new.TEXT_COLUMN1 = 'false' THEN new.TEXT_COLUMN1 := null; END IF;
  IF new.TEXT_COLUMN1 = 'false' THEN new.TEXT_COLUMN1 := null; END IF;
  IF new.TEXT_COLUMN1 = 'false' THEN new.TEXT_COLUMN1 := null; END IF;
END;

【问题讨论】:

  • 我不知道没有主键的方法。您正在处理一个缺少主键的数据库,您需要借助触发器来实现您的逻辑 - 到处都是危险信号!如果表不是很大,您可以在触发器中添加一个全面更新(随着表的增长,这将导致性能影响)。如果不需要立即更新该值,您可以运行一个计划的作业来进行全面更新。这两种解决方案都很糟糕,但这只是因为你一开始就遇到了糟糕的情况
  • 感谢您的建议。我对 Josh 建议的解决方案做了一个变体,它成功了(尽管在表模式更改时需要更改)。不幸的是,该表没有主键,但是唉,这是一种 OLAP 数据转储表,​​不同的源具有不同的键(因此每个键都必须是可空的)并且它们没有创建任何合成键因为他们很容易在 Oracle 中没有一个人生活

标签: sql sql-server tsql triggers


【解决方案1】:

您最好的选择是 INSTEAD OF 触发器。一般的想法是它会拦截你的插入,实际上根本不会插入任何行......除非你告诉它。

当您告诉它时,您可以进行替换。要实际插入行,只需在 INSTEAD OF 触发器中使用一些插入语句。别担心,它不会是递归的。

create trigger ReplaceFalseTrigger on table1 instead of insert as

insert into table1 (TEXT_COLUMN1) 
       select 
           case when TEXT_COLUMN1='false' then null else TEXT_COLUMN1 end
       from inserted;

这就是它的要点。我会把它留给你添加到你所有的其他神秘专栏中。

【讨论】:

    【解决方案2】:

    应该是这样的:

    update t  -- table being inserted into
         set TEXT_COLUMN1 = null
         from inserted i join
              t
              on t.id = i.id
         where t.TEXT_COLUMN1 = 'false';
    

    【讨论】:

    • 这里的问题是没有t.id列可以加入(这个表没有主键,我无法添加)
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 2022-01-24
    • 2011-09-11
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多