我有一个学校'项目'要处理,有一些表和一个表需要有一个约束,这对我来说没有用。
有一些表,如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上新手)
感谢。
答案 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 NULL
或IS 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)