【问题标题】:SQL - How to limit data entry of one attribute depending on another attribute?SQL - 如何根据另一个属性限制一个属性的数据输入?
【发布时间】:2016-03-19 18:00:30
【问题描述】:

下面是我要创建的表的 DDL。但是,我希望从“Expertise_animal”派生“Expertise_breed”属性。例如,如果在“Expertise_animal”中输入“Dog”,我不想输入猫的品种。我将如何实现这一目标? 我正在使用 SQL Server Management Studio 2012

CREATE TABLE tExpertise
(
Expertise_ID        int         NOT NULL  PRIMARY KEY, --E.G Data '001'
Expertise_type      varchar(8)  NOT NULL,              --E.G Data 'Domestic'
Expertise_animal    varchar(30) NOT NULL,              --E.G Data 'Dog'
Expertise_breed     varchar(30) NOT NULL               --E.G Data 'Poodle'
)

【问题讨论】:

  • 您想如何告诉您的 SQL Server Poodle 确实是 dog
  • 您可以创建检查约束
  • 该检查约束看起来像一个小型数据库。
  • 添加一个像CONSTRAINT AK_tExpertise_unique UNIQUE(Expertise_type, Expertise_animal, Expertise_breed) 这样的检查约束怎么样?但问题仍然存在:你想如何告诉 SQL Server bat 不是 bird?要么你硬编码它。但是,您也可以使用所有可能/允许的组合预先填写列表,否则一个人将不得不验证新条目,您只需在表的末尾添加一个IsVerified 位并要求用户验证数据。
  • 这取决于你的约束有多复杂。通常,如果简单,请使用检查约束。如果它很复杂,你需要使用触发器。

标签: sql sql-server sql-server-2012 ddl


【解决方案1】:

这是关系数据的情况,你应该使用关系表。

我要三个 动物分类——(家养、野生、其他) 动物物种(狗、猫、山羊) AnimalBreed(贵宾犬、比格犬) 动物物种将具有动物分类的外键,即 狗 - 家养 动物品种将具有动物物种的外键,即 比格犬——狗

【讨论】:

    【解决方案2】:

    您可以在插入和/或更新时创建触发器,并比较每一行的这两列。您可以通过“插入”别名引用插入的条目。

    如果您知道允许哪些映射(例如 dog x poodle),您可以将其存储在某个表中并在插入中加入它以过滤掉错误的映射。

    【讨论】:

      【解决方案3】:

      理论上,您想要的可以使用表级别constraints 来实现,执行此操作的通用方法如下(未测试):

      CREATE FUNCTION dbo.validateExpertise(
          @expertise_type varchar(8),
          @Expertise_animal varchar(30),
          @Expertise_breed varchar(30)   
      )
      RETURNS BIT
      AS
      BEGIN
          IF (@Expertise_animal == 'dog' AND @Expertise_breed != 'dog') 
              RETURN 0;
      
          -- other validations can come here
      
          RETURN 1;
      END
      GO
      
      -- add a table level constraint
      -- WITH NOCHECK can be used to not check existing data
      ALTER TABLE detailTable ADD CONSTRAINT chkExpertise
              CHECK (dbo.validateExpertise(expertise_type, Expertise_animal, Expertise_breed) = 1)
      

      虽然这可能对您有所帮助,但不建议在数据库级别进行如此复杂的验证。复杂的验证应该(至少)在应用程序的业务层中实现,通常在Logic tier(通常是 ASP.NET MVC、WCF 服务、Web 服务等)中(一些验证也放在表示层,以避免往返时间延迟。

      数据库主要用于数据持久性和获取。当然,欢迎使用简单的约束,例如 FKs、unique 约束、列级约束等,因为它们可以作为良好的安全网。

      另外,请记住,上述约束将针对表中的每个 INSERTUPDATE 触发,并且可能会严重降低涉及大量记录的查询的性能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-03
        • 1970-01-01
        相关资源
        最近更新 更多