複数のストアドプロシージャで同じコード


8

最近入社しましたが、多くのストアドプロシージャに同じコードセクションが繰り返し含まれていることに気づきました。発生したすべてのSPでそのコードの小さなセクションを変更する必要があったので、気が付きました:)

これはかなり大きなコードの塊で、約30行です。コードはinsertステートメントの一部であり、基本的には4つのテーブルをWHERE/AND、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に変更し、それが価値があるかどうかはわかりません。しかし、私のプログラマはこの状況を嫌っています。

なんらかのコードの再利用を実装する必要がありますか?ROIはありますか?私のオプションは何ですか?約100のストアドプロシージャを実行する必要があり、約1時間かかりました。

100個のSPは、20以上の異なるデータベースに分散しています。ビューを作成する権限があります。

回答:


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、2016年

1
テーブルは20のデータベースで複製されていますか?または、単一のデータベースのテーブルから選択していますか?
チャドマトックス2016年

テーブル(構造)は、これらの20のデータベースで複製されます。ストアドプロシージャは、ビジネスの性質(Obamacareの医療保険EDIレポート)のため、似ています(多くの場合、あちこちで同じコードチャンクを使用しています)。各データベースは異なる会社を表し、各ストアドプロシージャは異なる保険会社(ブルークロス/カイザーなど)を
表し

次に、各データベースのビューを複製する必要があります
Chad Mattox

2

このソリューションは、100以上のprocが同じことを行う必要性を置き換えるものです。あなたはプロシージャと関数を持っています。この関数は、すべての医療コードを文字列からテーブルに分割します。テーブルは、新しいプロシージャのCROSS APPLYで使用できます。この方法では、1つのプロシージャを呼び出すだけで済みます。もちろん、他のプロシージャを呼び出すすべてのコードを更新して、このコードだけを使用する必要があります。

--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 .....
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.