约束检查行和其他行是否同时不为空

时间:2015-10-03 10:10:36

标签: oracle

我有一个学校'项目'要处理,有一些表和一个表需要有一个约束,这对我来说没有用。

有一些表,如QUESTION,ANSWER和REACTION。 反应属于或者是问题或答案,但不是同时存在。 我有2行:

  question_id         NUMBER,
  answer_id           NUMBER,

两者都不为null,因为cant为null,但不是在同一时间。

我已经制定了约束但不起作用..

  /* CHECK if reaction belongs to an question or a answer             NOT WORKING YET*/
CONSTRAINT CHECK_question_or_answer CHECK((answer_id != NULL AND question_id = NULL) OR (answer_id = NULL OR question_id != NULL))

已经测试了约束,我可以插入一个没有question_id或answer_id的值。 我希望它有点清楚,如果没有,我很高兴你试着更好地解释自己。 (仍然在SQL上新手)

感谢。

3 个答案:

答案 0 :(得分:2)

你的约束:

CONSTRAINT CHECK_question_or_answer CHECK((answer_id != NULL AND profile_id = NULL) OR (answer_id = NULL OR profile_id != NULL))

总是 FALSE

您需要使用IS NULLIS NOT NULL,如:

CONSTRAINT CHECK_question_or_answer CHECK((answer_id IS NOT NULL AND profile_id IS NULL) OR (answer_id IS NULL OR profile_id IS NOT NULL))

这是因为比较运算符!= , = , > , <,NULL结合生成NULL并被视为false。

演示:

SELECT 1
FROM dual
WHERE 1 IS NOT NULL;

SELECT 1
FROM dual
WHERE 1 != NULL;

来自doc

  

NULL值表示缺失或未知数据。 NULL值用作   占位符或作为列中的默认条目以指示否   实际数据存在。 NULL在SQL中是无类型的,这意味着它是   不是整数,字符或任何其他特定数据类型。

     

请注意,NULL与空数据字符串或   数值&#39; 0&#39;。 NULL表示没有值,而   空字符串和数字零都表示实际值。

     

虽然可以分配NULL值,但不能将其等同   任何东西,包括它自己。

     

因为NULL不表示或等同于数据类型,所以不能   使用任何比较运算符测试NULL值,例如=,&lt;或   &LT;&GT;

     

IS NULL和IS NOT NULL运算符用于测试NULL   值。

答案 1 :(得分:0)

反过来做。将主表的id放在其他类似的

question table
--------------
id
text
...


answers table
-------------
id
question_id
text
...


reactions table
---------------
id
question_id
text
...

question_id永远不会为空。然后,您可以使用left join从两个表中获取结果 - 其中一个没有结果。

select *
from questions q
left join answers a on a.question_id = q.id
left join reactions r on r.question_id = q.id

答案 2 :(得分:0)

虽然@ lad2025s的答案适用于两列,但如果你想将方法扩展到两个以上,可能会有点麻烦。

灵活的替代方案是:

check ((case when answer_id   is null then 0 else 1 end +
        case when question_id is null then 0 else 1 end ) = 1)

它可以很好地检查任意数量的列的特定空值(或非空值)。

例如,如果您有column_1,column_2,column3和column_4,并且希望至少有一个非空,那么:

check ((case when column_1 is null then 0 else 1 end +
        case when column_2 is null then 0 else 1 end +
        case when column_3 is null then 0 else 1 end +
        case when column_4 is null then 0 else 1 end ) >= 1)