0

我有两个冗余代码的存储过程。SP 将根据从中选择的表而有所不同。我想结合这两个SP。请帮忙。

主要的SP是:

CREATE PROCEDURE [dbo].[spGetEmployeesBySearchString]            
-------------
-------------
@OtherListType_ID INT
@manager_employee_number VARCHAR(255)
-------------
-------------
DECLARE @IsGetFullTeamUnderManager bit=0
IF (@OtherListType_ID=3 AND @manager_employee_number IS NOT NULL)
    SET @IsGetFullTeamUnderManager = 1

IF (@IsGetFullTeamUnderManager=1)
BEGIN
    EXEC spFullTeamUnderManager <<Parameters>>
    RETURN
END

SELECT e.a,e.b,e.c,e.d,......
FROM Employee emp
INNER JOIN .....
WHERE ..........

第二个存储过程是:

CREATE PROCEDURE [dbo].[spFullTeamUnderManager]            
-------------
-------------
-------------
SELECT e.a,e.b,e.c,e.d,......
FROM dbo.fnFullTeamUnderManager(@manager_employee_number) emp 
INNER JOIN .....
WHERE ..........

在主 SP 中,基于 @OtherListType_ID 的值,我调用了第二个 SP。但是两个存储过程中的 select 语句、连接条件和 where 条件保持不变。我需要删除多余的代码。请帮忙。

4

3 回答 3

1

通常,您不能在FROM子句中对行集源进行参数化。您可以执行以下操作,并希望优化器足够聪明以正确执行此操作:

SELECT e.a,e.b,e.c,e.d,......
FROM (
 SELECT * FROM dbo.fnFullTeamUnderManager(@manager_employee_number) WHERE @IsGetFullTeamUnderManager=1
 UNION ALL
 SELECT * FROM Employee WHERE @IsGetFullTeamUnderManager=0
) emp 
INNER JOIN .....
WHERE ..........

如果函数和Employee不共享完全相同的列,您将不得不明确命名公共列而不是使用SELECT *- 有些人可能坚持认为您应该这样做,但今天我处于“完成”的心情.

于 2013-03-19T08:07:17.117 回答
0
CREATE PROCEDURE [dbo].[spGetEmployeesBySearchString]            
-------------
-------------
@OtherListType_ID INT,
@manager_employee_number VARCHAR(255)
-------------
-------------
DECLARE @IsGetFullTeamUnderManager bit=0
IF (@OtherListType_ID=@FullTeam AND @manager_employee_number IS NOT NULL)
    SET @IsGetFullTeamUnderManager = 1

IF (@IsGetFullTeamUnderManager=1)
BEGIN    
    SELECT e.a,e.b,e.c,e.d,......
    FROM dbo.fnFullTeamUnderManager(@manager_employee_number) emp 
    INNER JOIN .....    
    WHERE ..........    
END

SELECT e.a,e.b,e.c,e.d,......
FROM Employee emp
INNER JOIN .....
WHERE ..........
于 2013-03-19T07:53:15.680 回答
0
CREATE PROCEDURE [dbo].[spGetEmployeesBySearchString]            
-------------
-------------
@OtherListType_ID INT
@manager_employee_number VARCHAR(255)
-------------
-------------

-- Me
DECLARE @SQL varchar(3000);
DECLARE @TableName varchar(30);
SET @TableName = 'Employee ';



DECLARE @IsGetFullTeamUnderManager bit=0
IF (@OtherListType_ID=3 AND @manager_employee_number IS NOT NULL)
    SET @IsGetFullTeamUnderManager = 1

IF (@IsGetFullTeamUnderManager=1)
BEGIN
    SET @TableName = 'dbo.fnFullTeamUnderManager(' + @manager_employee_number +') ';
END

SET @SQL = 'SELECT e.a,e.b,e.c,e.d
            FROM ' + @TableName + ' emp
            INNER JOIN .....
            WHERE a = ' + convert(varchar(4), @aNumber);

EXEC(@SQL);

您还应该知道执行动态 sql 语句的更好方法。

使用EXEC SP_EXECUTESQL(@SQL)而不是EXEC(@SQL)更有可能促进查询计划重用和提高安全性。此外,使用这种方法可以确保传递给查询的数据值是正确的数据类型。

更多阅读 在 SQL Server 中执行动态 SQL 命令

于 2013-03-19T08:06:47.857 回答