多个存储过程中的相同代码


8

我最近加入一家公司,我只是注意到许多存储过程在整个过程中都重复了相同的代码部分。我注意到了,因为我的任务是在每个发生的SP中更改该代码的一小部分:)

这是相当庞大的代码块,大约30行。该代码是插入语句的一部分,它基本上将4个表连接在一起,而WHERE/AND条件实际上并没有真正从SP变为SP。它看起来类似于以下内容:

...
...
FROM <TableOne>
  INNER JOIN <TableTwo> ON ...
    AND .....
    AND .....
  LEFT JOIN <TableThree> ON ...
    AND .....
    AND .....
WHERE .....
  AND .....
  AND .....
  AND MedicalPlanCode IN ('abc', 'def', 'ghi')

从SP更改为SP的唯一部分是值(“ abc”,“ def”,“ ghi”

这些值的数量也可以不同,因此某些SP的值为2,其他SP的值为5,等等。

我想到的所有内容都将那部分代码更改为动态SQL,但不确定是否值得。但是,我里面的程序员讨厌这种情况。

我应该尝试实现某种形式的代码重用吗?有投资回报率吗?我有什么选择?我不得不经历大约100个存储过程,这花了大约一个小时。

100个SP分布在20个左右的不同数据库中。我确实具有创建视图的权限。

Answers:


11

这应该为您工作:

CREATE VIEW MyView AS
SELECT <colList>
FROM <TableOne>
INNER JOIN <TableTwo> ON ...
AND .....
AND .....
LEFT JOIN <TableThree> ON ...
AND .....
AND .....
WHERE .....
AND .....
AND .....

然后在Procs中替换为:

...
FROM MyView
WHERE
MedicalPlanCode IN ('abc', 'def', 'ghi')

有没有办法使单个视图传播到需要它的所有数据库?
Jeff.Clark '16

1
这些表是否在20个数据库中重复?还是他们从单个数据库的表中选择?
乍得马托克斯

这些表(结构)在这20个数据库中重复。由于业务的性质,存储过程是相似的(通常在这里和那里使用相同的代码块)-针对奥巴马医改的健康保险EDI报告。每个数据库代表一个不同的公司,每个存储过程代表一个不同的保险公司(Blue Cross / Kaiser / etc ...)
Jeff.Clark,2016年

然后,您需要为每个数据库复制视图
Chad Mattox

2

该解决方案将代替需要100个以上的proc来执行相同操作的需求。你有一个过程和一个功能。该函数将您的所有医疗代码从字符串拆分为表格,该表格可在新proc的CROSS APPLY中使用。这样,您只需要调用一个proc。当然,您必须更新所有调用其他proc的代码才能仅使用此代码。

--gfn_ParseList
IF NOT EXISTS (SELECT * FROM sys.objects WHERE type in ('FN', 'IF', 'TF', 'FS', 'FT') AND name = 'gfn_ParseList')
    EXEC sp_executesql N'CREATE FUNCTION gfn_ParseList RETURNS @paresedIDs AS BEGIN SELECT 1 ParsedValue, 1 PositionID RETURN END'
GO


ALTER FUNCTION gfn_ParseList (@strToPars VARCHAR(8000), @parseChar CHAR(1))
RETURNS @parsedIDs TABLE
     (ParsedValue VARCHAR(255), PositionID INT IDENTITY)
AS
BEGIN

DECLARE 
    @startPos INT = 0
    , @strLen INT = 0

WHILE LEN(@strToPars) >= @startPos
    BEGIN

        IF (SELECT CHARINDEX(@parseChar,@strToPars,(@startPos+1))) > @startPos
            SELECT @strLen  = CHARINDEX(@parseChar,@strToPars,(@startPos+1))    - @startPos
        ELSE
            BEGIN
                SET @strLen = LEN(@strToPars) - (@startPos -1)

                INSERT @parsedIDs
                SELECT RTRIM(LTRIM(SUBSTRING(@strToPars,@startPos, @strLen)))
                BREAK
            END

        SELECT @strLen  = CHARINDEX(@parseChar,@strToPars,(@startPos+1))    - @startPos

        INSERT @parsedIDs
        SELECT RTRIM(LTRIM(SUBSTRING(@strToPars,@startPos, @strLen)))

        SET @startPos = @startPos+@strLen+1
    END
RETURN
END 


--New sp
create proc usp_ReturnSomeData (@medicalPlanCodes nvarchar(1000))
as

select YourColumn1, YourColumn2...
FROM <TableOne>
  CROSS APPLY gfn_ParseList(@medicalPlanCodes,',') p
  INNER JOIN <TableTwo> ON ...
    AND .....
    AND .....
  LEFT JOIN <TableThree> ON ...
    AND .....
    AND .....
WHERE .....
  AND .....
  AND .....
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.