我的数据库中有一个存储过程,用于将员工详细信息从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 =有效
我的要求是:我需要使用相同的程序在以下场景中获得员工:
EMP_ACTIVE = 1
)EMP_ACTIVE = 0
)EMP_PK = @P_PK
)EMP_PK = @P_PK
的特定员工(即使该@P_PK员工处于非活动状态)但没有重复记录。我的问题是,我无法更改存储过程的签名(抱歉,我无法在此解释原因),这意味着我无法更改/添加参数和数据类型在存储过程/表中。但我可以更改存储过程的正文/查询部分。
我知道这可能是一个简单的选择查询,如
SELECT EMP_PK, EMP_NAME
FROM EMPLOYEE
WHERE ?1 AND/OR ?2
但是我如何在这里管理WHERE
条件?在上述5个场景中,我可以从我的应用程序传递给现有存储过程参数的值是什么?
注意:EMP_ACTIVE
列仅包含0
和1
(0:InActive / 1:有效)。在我的应用程序中,我知道我想要应用所有这些场景,这是我需要加载所有员工或所有活动/非活动员工等。但我需要使用现有的存储过程来实现这一点,我可以&#39 ; t向存储过程添加其他参数。
答案 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