构想
在 Org_Structure 中,有部门和办公室的独特组合。在 Emp_Positions 表中,每个员工都被分配到组织结构中的部门/办公室或“Chain”的特定组合。但是一些员工不应该属于办公室,因此他们被分配到 office_id 列为NULL的链。 在第二张图片上,这样的员工用红色着色。
错误
提供的存储过程只能找到dep_id和office_id都为NOT NULL的链的员工。如果在某些记录中office_id为NULL,或者dep_id为NULL,则不会显示此记录。看到第二张图片,结果中从不显示红色记录。一旦我用值替换NULL,就会显示它。如果我用NULL替换任何行的任何列,则不会显示整行。
我试图找到修复它的方法,但我无法弄明白......这里的伙计已经帮助我使这个程序工作了,我非常感谢,但是WHERE子句仍然是错误的......
这是存储过程:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE FilterEmpList
@empName nvarchar(250) = null,
@empDepID int = null,
@empOfficeID int = null,
@empPosID int = null
AS
BEGIN
SELECT
E.emp_id,
E.emp_name,
P.pos_name,
D.dep_name,
O.office_name
FROM dbo.Org_Structure OS
JOIN dbo.Emp_Positions EP ON OS.chain_id=EP.chain_id
JOIN dbo.Employees E ON EP.emp_id=E.emp_id
JOIN dbo.Positions P ON P.pos_id=EP.pos_id
JOIN dbo.Departments D ON D.dep_id=OS.dep_id
LEFT JOIN dbo.Offices O ON O.office_id=OS.office_id
WHERE (E.emp_name LIKE '%'+@empName+'%' OR @empName IS NULL)
AND OS.dep_id = ISNULL(@empDepID, OS.dep_id)
AND OS.office_id = ISNULL(@empOfficeID, OS.office_id)
AND EP.pos_id = ISNULL(@empPosID, EP.pos_id)
END
*添加 LEFT JOIN 后,它仍然无法正常工作
问题已解决
查看评论
答案 0 :(得分:2)
问题是固定的,但我注意到没有解释为什么它被修复了。所以我们走了:
在SQL中,任何类型的变量都可以接收值NULL。此值表示缺少值或未知值。 NULL是特殊的,因为任何在一侧或两侧使用NULL的相等或不等式运算符的结果不是true或false,而是NULL。
所以:
'Hello' = 'Hello' -> true
'Hello' = 'World' -> false
可是:
'Hello' = NULL -> NULL
NULL = NULL -> NULL
这意味着SQL使用具有三个可能值的布尔系统。按照这些规则将NULL添加到通常的“true”和“false”:
TRUE and NULL = NULL
FALSE and NULL = FALSE
NULL and NULL = NULL
TRUE or NULL = TRUE
FALSE or NULL = NULL
NULL or NULL = NULL
NOT NULL = NULL
在这种情况下,如果“office_id”或“dep_id”为NULL,那么条件的结果
OS.dep_id = ISNULL(@empDepID, OS.dep_id)
或
OS.office_id = ISNULL(@empOfficeID, OS.office_id)
将为NULL。由于具有NULL值的逻辑AND的结果始终为NULL或FALSE,因此处理整个子句子句的结果必须为NULL或FALSE,并且因为只有在子句的结果为TRUE时才返回行,所以没有行归还。