代码之家  ›  专栏  ›  技术社区  ›  Caveatrob

SQL以确保传入ID不在字段中

sql
  •  0
  • Caveatrob  · 技术社区  · 15 年前

    我有3个字段(1年级,2年级,3年级),我要输入一个年级ID,我想确保3个字段中没有一个是年级ID(如果它们不是空的话)。

    我做得对吗?

    WHERE @fycuserid <> ISNULL(grader1_fyc,0)
    AND @fycuserid <> ISNULL(grader2_fyc,0)
    AND @fycuserid <> ISNULL(grader3_fyc,0)
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Bob Jarvis - Слава Україні    15 年前

    好吧,没关系,还有更好的。你所描述的设计是可以的-它可能会做你想要的-但有一些方法可以使它更好。

    事实上,有问题的表有三个字段,所有字段基本上都包含相同的信息——评分者的ID。如您所见,要检查这些字段中的每一个,必须编写特殊代码以将过程参数与1级、2级和3级进行比较,并且每次进行类似比较时都必须重复此特殊代码。这没关系,但我想你会发现这会有点麻烦。

    在进行数据库规范化时,应用了某些规则,有时必须更改数据库设计。要确定表是否处于第一正常形式,需要检查的基本内容是

    1. 该表是否忠实地代表一种关系,以及
    2. 有重复组吗?

    从你的帖子中很难判断这个表是否正确地表示了一个关系,但是从给出的信息中很容易看出有一组重复的字段——三年级的字段。这三个字段可以从此表中删除并添加一个新表。假设文章中提到的表是论文,它包含一个名为id_论文的主键。一个用来保存给论文打分的评分者信息的表格可以称为“论文评分者”,它可能如下所示:

    CREATE TABLE PAPER_GRADERS
      (ID_PAPER    NUMBER
         REFERENCES PAPERS(ID_PAPER),
       ID_GRADER   NUMBER
         REFERENCES GRADERS(ID_GRADER),
       PRIMARY KEY (ID_PAPER, ID_GRADER));
    

    现在,如果一篇论文是由一个给定的分级机评分的,那么将在论文分级机中创建一行,其中包含论文的ID和分级机的ID。如果一篇论文是由两个评分员评分的,那么在论文评分员中会创建两行,每一行都有相同的ID,但每一行都有不同评分员的ID。这就是所谓的“一对多”关系——在这种情况下,一篇论文可以由许多评分员进行评分,而且一篇论文的评分员数量没有限制。

    现在,在最初提到的过程中,不必显式检查三个分级器字段中是否有一个字段包含传递给该过程的分级器的ID,SQL会有所不同-您需要对纸张和纸张分级器进行内部联接,以查找与参数匹配的现有分级器。这样做的选择看起来像

    SELECT *
      FROM PAPERS p
    INNER JOIN PAPER_GRADERS g
      USING (ID_PAPER)
    WHERE g.GRADER = @fycuserid
    

    这种类型的数据库构造非常方便。

    我希望这有帮助。

        2
  •  1
  •   machineghost    15 年前

    首先,不能只说“SQL”,因为每个数据库都有自己的SQL压力。例如,在DB2中,您会说:

    WHERE @fycuserid <> COALESCE(grader1_fyc, 0)
    

    也就是说,假设您的DB的值等于coalesce,那么您的代码对我来说似乎很好。