Stesso codice in più stored procedure


8

Di recente mi sono unito a un'azienda e ho appena notato che molte delle procedure memorizzate hanno la stessa sezione di codice ripetuta dappertutto. Ho notato che mi è stato assegnato il compito di modificare una piccola sezione di quel codice in ogni SP che si è verificato :)

È un pezzo abbastanza pesante di codice, circa 30 righe. Il codice fa parte di un'istruzione insert e fondamentalmente unisce 4 tabelle con WHERE/ANDcondizioni che in realtà non cambiano da SP a SP. Sembra simile al seguente:

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

L'unica parte che cambia da SP a SP sono i valori ( 'abc', 'def', 'ghi' )

Possono esserci anche quantità diverse di tali valori, quindi alcuni SP avranno 2 valori, altri ne avranno 5, ecc.

Tutto ciò che penso cambia quella sezione di codice in SQL dinamico e non sono sicuro che ne valga la pena. Tuttavia, il programmatore in me odia questa situazione.

Dovrei provare a implementare una qualche forma di riutilizzo del codice? Avrebbe un ROI? Quali sono le mie opzioni? Ho dovuto passare attraverso ~ 100 stored procedure, che hanno richiesto circa un'ora.

I 100 SP sono distribuiti su circa 20 database diversi. Ho i permessi per creare una vista.

Risposte:


11

Questo dovrebbe funzionare per te:

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

Quindi sostituire in Procs con:

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

C'è un modo per far propagare quella vista singola a tutti i database che ne hanno bisogno?
Jeff.Clark,

1
Le tabelle sono duplicate nei 20 database? O stanno selezionando dalle tabelle in un singolo database?
Chad Mattox,

Le tabelle (struttura) sono duplicate in quei 20 database. Le Stored Procedures sono simili (spesso utilizzano gli stessi blocchi di codice qua e là) a causa della natura del business: report EDI sull'assicurazione sanitaria per Obamacare. Ogni database rappresenta una società diversa, ogni Stored Procedure rappresenta un diverso vettore assicurativo (Blue Cross / Kaiser / ecc ...)
Jeff.Clark,

Dovresti duplicare la vista per ogni database quindi
Chad Mattox,

2

Questa soluzione sostituirà la necessità di avere 100+ proc che fanno la stessa cosa. hai un proc e una funzione. La funzione divide tutti i codici medici da una stringa a una tabella che può essere utilizzata in una CROSS APPLY nel nuovo proc. In questo modo devi solo chiamare il proc. Ovviamente dovresti aggiornare tutto il codice chiamando gli altri proc per usare solo questo.

--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 .....
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.