如何在不同的场景中获取Employee记录

时间:2017-01-04 05:12:39

标签: sql sql-server tsql stored-procedures

我的数据库中有一个存储过程,用于将员工详细信息从Employee表返回给我的应用程序。

SPHR_Employee_Get(@P_PK INT,@P_ACTIVE TINYINT)

Employee表结构是

EMP_PK INT, EMP_NAME NVARCHAR(200), EMP_ACTIVE TINYINT

EMP_ACTIVE的值:0 = InActive / 1 =有效

我的要求是:我需要使用相同的程序在以下场景中获得员工:

  1. 所有员工
  2. 所有在职员工(EMP_ACTIVE = 1
  3. 所有非活动员工(EMP_ACTIVE = 0
  4. 仅限特定员工(EMP_PK = @P_PK
  5. 所有活跃员工+ EMP_PK = @P_PK的特定员工(即使该@P_PK员工处于非活动状态)但没有重复记录。
  6. 我的问题是,我无法更改存储过程的签名(抱歉,我无法在此解释原因),这意味着我无法更改/添加参数和数据类型在存储过程/表中。但我可以更改存储过程的正文/查询部分。

    我知道这可能是一个简单的选择查询,如

    SELECT EMP_PK, EMP_NAME 
    FROM EMPLOYEE 
    WHERE ?1 AND/OR ?2
    

    但是我如何在这里管理WHERE条件?在上述5个场景中,我可以从我的应用程序传递给现有存储过程参数的值是什么?

    注意:EMP_ACTIVE列仅包含01(0:InActive / 1:有效)。在我的应用程序中,我知道我想要应用所有这些场景,这是我需要加载所有员工或所有活动/非活动员工等。但我需要使用现有的存储过程来实现这一点,我可以&#39 ; t向存储过程添加其他参数。

3 个答案:

答案 0 :(得分:1)

这就是你想要的

ALTER SPHR_Employee_Get(@P_PK INT,@P_ACTIVE TINYINT)
AS
BEGIN
    SELECT EMP_PK, EMP_NAME 
    FROM EMPLOYEE 
    WHERE (EMP_PK = @P_PK OR @P_PK = -1);
      AND (EMP_ACTIVE = @P_ACTIVE OR @P_ACTIVE = -1)
END

现在通过发送不同的参数值来执行它

--   All Employees
EXEC SPHR_Employee_Get -1, -1

--    All Active Employees
EXEC SPHR_Employee_Get -1, 1

-- All Inactive Employees
EXEC SPHR_Employee_Get -1, 0

-- Only a particular employee (EMP_PK = @P_PK)
EXEC SPHR_Employee_Get 123, -1

/*
All Active Employees 
+ a Particular employee who's EMP_PK = @P_PK (even if that @P_PK employee is inactive)
 - But no duplicate records.
*/
EXEC SPHR_Employee_Get -1, 1

EXEC SPHR_Employee_Get 123, -1
来自第5个场景的评论

编辑

ALTER SPHR_Employee_Get(@P_PK INT, @P_ACTIVE TINYINT)
AS
BEGIN
    IF (@P_ACTIVE <> -2)
    BEGIN
        SELECT EMP_PK, EMP_NAME 
        FROM EMPLOYEE 
        WHERE (EMP_PK = @P_PK OR @P_PK = -1);
          AND (EMP_ACTIVE = @P_ACTIVE OR @P_ACTIVE = -1)
    END

    IF (@P_ACTIVE = -2)
    BEGIN
        SELECT EMP_PK, EMP_NAME 
        FROM EMPLOYEE 
        WHERE EMP_ACTIVE = 1
        UNION 
        SELECT EMP_PK, EMP_NAME 
        FROM EMPLOYEE 
        WHERE EMP_PK = @P_PK
    END
END

呼叫将是

 EXEC SPHR_Employee_Get 123, -2

编辑2: TinyInt数据类型

的问题
CREATE PROCEDURE SPHR_Employee_Get(@P_PK INT, @P_ACTIVE TINYINT)
AS
BEGIN
    /*
        @P_ACTIVE VALUES in Different executions
        --1 All Employees
        --2 All Active Employees
        --3 All Inactive Employees
        --4 Only a particular employee (EMP_PK = @P_PK)
        --5 All Active Employees 
+ a Particular employee who's EMP_PK = @P_PK (even if that @P_PK employee is inactive)
 - But no duplicate records.

    */

    SELECT EMP_NBR, FIRST_NME 
    FROM EMPLOYEEPROFILE
    WHERE ((@P_ACTIVE = 1)
    OR (@P_ACTIVE=2 AND ACTIVE_IND=1)
    OR (@P_ACTIVE=3 AND ACTIVE_IND=0)
    OR (@P_ACTIVE=4 AND EMP_NBR=@P_PK)
    OR (@P_ACTIVE=5 AND ACTIVE_IND=1)
    )

    UNION 

    SELECT EMP_NBR, FIRST_NME 
    FROM EMPLOYEEPROFILE
    WHERE @P_ACTIVE=5 AND EMP_NBR=@P_PK

END

执行将是

--1 All Employees

EXEC SPHR_Employee_Get NULL,1

--2 All Active Employees

EXEC SPHR_Employee_Get NULL,2

--3 All Inactive Employees

EXEC SPHR_Employee_Get NULL,3

--4 Only a particular employee (EMP_PK = @P_PK)

EXEC SPHR_Employee_Get 123,4

--5 All Active Employees + Passed Emp(Active/Inactive)

EXEC SPHR_Employee_Get 123,5

答案 1 :(得分:1)

经过一些研究和@Shakeer Mirza的建议,通过简单的查询解决了所有场景。

SELECT  EMP_PK, EMP_NAME
FROM    EMPLOYEES
WHERE   (       EMP_PK      = ISNULL(@P_PK,EMP_PK)
            OR  EMP_ACTIVE  = ISNULL(@P_ACTIVE,EMP_ACTIVE)
        )

方案的参数值为:

PK          Active          RETURNS
-------     -----------     --------
-1          NULL            All Records
-1          1               All Active Records
-1          0               All Inactive Records
PK_Value    2(>1)           Record for PK
PK_Value    1               All active records and the PK value record,
                            even if PK value record is inactive

答案 2 :(得分:0)

尝试这样简单在存储过程中添加一个额外的参数来处理所需的场景。

CREATE PROCEDURE SPHR_Employee_Get
    @P_PK INT,
    @P_ACTIVE TINYINT,
    @P_Flag INT --- Add @P_Flag parameter to handle requested scanerio
AS
BEGIN

IF (@P_Flag = 1) ------- All Employees
BEGIN

Select EMP_PK,EMP_NAME, EMP_ACTIVE FROM Employees

END
ELSE IF (@P_Flag = 2) ----------- All Active Employees (EMP_ACTIVE = 1)
BEGIN

Select EMP_PK,EMP_NAME, EMP_ACTIVE FROM Employees
Where EMP_ACTIVE = @P_ACTIVE
END
ELSE IF (@P_Flag = 3) ------------ All Inactive Employees (EMP_ACTIVE = 0)
BEGIN

Select EMP_PK,EMP_NAME, EMP_ACTIVE FROM Employees
Where EMP_ACTIVE = @P_ACTIVE
END
ELSE IF (@P_Flag = 4) -------------- Only a particular employee (EMP_PK = @P_PK)
BEGIN

Select EMP_PK,EMP_NAME, EMP_ACTIVE FROM Employees
Where EMP_PK = @P_PK
END
ELSE IF (@P_Flag = 5) ------------ All Active Employees + a Particular employee who's EMP_PK = @P_PK (even if that @P_PK employee is inactive)- But no duplicate records.
BEGIN

Select Distinct EMP_PK,EMP_NAME, EMP_ACTIVE FROM Employees
Where (EMP_PK = @P_PK AND EMP_ACTIVE = 1) OR (EMP_PK = @P_PK AND EMP_ACTIVE = 0)
END


END