Kode yang sama dalam beberapa prosedur tersimpan

8

Saya baru-baru ini bergabung dengan sebuah perusahaan, dan saya baru saja memperhatikan bahwa banyak dari prosedur yang tersimpan memiliki bagian kode yang sama berulang. Saya perhatikan karena saya ditugaskan untuk mengubah bagian kecil dari kode itu di setiap SP yang terjadi :)

Ini adalah potongan kode yang cukup besar, sekitar 30 baris. Kode adalah bagian dari pernyataan penyisipan, dan pada dasarnya menggabungkan 4 tabel bersama dengan WHERE/ANDkondisi yang tidak benar-benar berubah dari SP ke SP. Itu terlihat mirip dengan di bawah ini:

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

Satu-satunya bagian yang berubah dari SP ke SP adalah nilainya ( 'abc', 'def', 'ghi' )

Ada juga jumlah yang berbeda dari nilai-nilai itu, sehingga beberapa SP akan memiliki 2 nilai, yang lain akan memiliki 5, dll ...

Semua yang saya pikirkan tentang perubahan bagian kode menjadi SQL dinamis, dan saya tidak yakin apakah itu layak. Namun, programmer dalam diriku membenci situasi ini.

Haruskah saya mencoba menerapkan beberapa bentuk penggunaan kembali kode? Apakah ada ROI? Apa saja pilihan saya? Saya harus melalui ~ 100 prosedur tersimpan, yang memakan waktu sekitar satu jam.

100 SP tersebar di 20 atau lebih basis data yang berbeda. Saya memiliki izin untuk membuat tampilan.

Jeff.Clark
sumber

Jawaban:

11

Ini seharusnya bekerja untuk Anda:

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

Kemudian ganti dengan Procs dengan:

...
FROM MyView
WHERE
MedicalPlanCode IN ('abc', 'def', 'ghi')
Chad Mattox
sumber
Apakah ada cara untuk membuat tampilan tunggal menyebar ke semua database yang membutuhkannya?
Jeff.Clark
1
Apakah tabel diduplikasi dalam 20 database? Atau mereka memilih dari tabel dalam satu basis data?
Chad Mattox
Tabel (struktur) diduplikasi dalam 20 database tersebut. Prosedur Tersimpan serupa (sering menggunakan potongan kode yang sama di sana-sini) karena sifat bisnis - Pelaporan EDI Asuransi Kesehatan untuk Obamacare. Setiap Database mewakili perusahaan yang berbeda, setiap Prosedur yang Disimpan mewakili Pengangkut Asuransi yang berbeda (Blue Cross / Kaiser / dll ...)
Jeff.Clark
Anda perlu menduplikasi tampilan untuk setiap basis data
Chad Mattox
2

Solusi ini akan menggantikan kebutuhan untuk memiliki 100+ procs melakukan hal yang sama. Anda memiliki proc dan fungsi. Fungsi ini membagi semua kode medis Anda dari string ke tabel yang dapat digunakan dalam CROSS BERLAKU di proc baru. Dengan cara ini Anda hanya perlu memanggil satu proc. Tentu saja Anda harus memperbarui semua kode yang memanggil procs lain untuk menggunakan yang ini saja.

--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 .....
Steve Mangiameli
sumber