【问题标题】:Creating a trigger in order to maintain an intermediate table integrity创建触发器以维护中间表的完整性
【发布时间】:2013-11-15 19:33:36
【问题描述】:

我用下图创建了一个数据库:

http://imagizer.imageshack.us/v2/800x489q90/440/o1yu.png

TrainerPokemon 表表示出现的口袋妖怪(属于训练师),而 Pokemon 表表示口袋妖怪“物种”。一种特定的口袋妖怪可能拥有某些能力,但这只口袋妖怪的出现可能只具有一种能力(TrainerPokemon 表中的AbilityID 列)。

这是我的问题:我试图创建一个触发器以防止将任何其他功能(不同于PokemonAbility 表中指定的功能)插入/更新到TrainerPokemon 表中的寄存器,但是我没有成功。 有人对触发器有任何想法吗?这个数据库模型的新想法也很受欢迎。 (重要提示:我使用的是 SQL Server 2012)

【问题讨论】:

  • 你不应该在这里使用触发器,你应该修复你的架构。 TrainerPokemon 表上的AbilityId 列实际上应该是PokemonAbility 表的ID,它应该引用该列。 (这就留下了一个问题,即你可能会以与那里的口袋妖怪不同的能力结束,但这就是你为图表建模的方式)
  • 那么我应该使用什么来维护数据完整性?
  • 对于你在这里解释的特殊情况,添加我刚才说的参考。遗憾的是,我没有时间查看您的整个架构,了解您真正想要的是什么,然后创建一个新图表
  • PeeeeeeeeeekaCHUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU!
  • 要实现你所需要的,你真的应该合并表TrainerPokemonPokemonAbility

标签: sql sql-server triggers


【解决方案1】:

类似这样的东西(在我的脑海中打字):

CREATE TRIGGER trg_pok_abil ON TrainerPokemon FOR UPDATE, INSERT
AS
BEGIN
    IF EXISTS (
        SELECT *
        FROM inserted
        WHERE inserted.AbilityID NOT (
            SELECT AbilityID
            FROM PokemonAbility
            WHERE PokemonAbility.PokemonID = inserted.PokemonID
        )
    BEGIN
        ROLLBACK
    END
END

【讨论】:

  • 在解释操作失败原因的RaIsError 声明中折腾通常很有帮助。
  • 同意。只是一个快速的努力 tbh
  • 应该插入什么表格?我试过用它来代替 TrainerPokemon,但这样就不可能与之结合
  • "inserted" 是一个系统表,表示添加的行。 “deleted”表示已删除的行。因此,更新将有一个“已删除”表和一个“插入”表。
  • 换句话说,完全按照我说的去做,不需要改变。
【解决方案2】:

您可以在 pokemonid 和能力 ID 上的 pokemonability 和 trainerpokemon 之间添加一个两列外键约束。

HTH

【讨论】:

  • 这可能会错误地选择不相关的口袋妖怪/能力组合
  • 我实际上认为 ERD 需要一些修改。 pokemonability pokemontrainer 可能需要与 pokemon 的逻辑键合并到一个表中,trainer 能力取决于基数。即一个口袋妖怪可以拥有一个以上的能力训练师。猜测 pokemantypes 不应该是一个单独的表,除非一个 pokemon 可以有多种类型。
猜你喜欢
  • 2018-06-21
  • 2017-01-07
  • 1970-01-01
  • 2017-05-27
  • 2019-04-20
  • 2013-03-26
  • 1970-01-01
  • 2019-07-30
  • 2020-08-04
相关资源
最近更新 更多