2

[删除了公司机密信息或图形]

概念

Org_Structure中有部门和办公室的独特组合。在Emp_Positions表中,每个员工都被分配到组织结构中的部门/办公室或“链”的特定组合。但是有些员工不应该属于办公室,所以他们被分配到office_id 列为NULL 的链中。

错误

提供的存储过程只能找到那些 dep_id 和 office_id 都不是 NULL 的链的员工。如果某些记录中office_id 为NULL,或者dep_id 为NULL,则不会显示该记录。看第二张图片,红色的记录永远不会显示在结果中。一旦我用一个值替换 NULL,它就会显示出来。如果我用 NULL 替换任何行的任何列,则不会显示整行。

这是存储过程:

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它仍然不起作用

4

1 回答 1

1

问题已解决,但我注意到没有解释为什么它已修复。所以我们开始:

在 SQL 中,任何类型的变量都可以接收 NULL 值。此值旨在表示缺少值或未知值。NULL 是特殊的,因为任何等式或不等式运算符的一侧或两侧都带有 NULL 的结果不是真或假,而是 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 值进行逻辑与的结果始终为 NULL 或 FALSE,因此处理整个子句子句的结果必须为 NULL 或 FALSE,并且由于仅当子句的结果为 TRUE 时才返回一行,因此没有行被退回。

于 2013-06-10T21:57:03.940 回答