Cùng một mã trong nhiều thủ tục được lưu trữ


8

Gần đây tôi đã gia nhập một công ty và tôi chỉ nhận thấy rằng nhiều thủ tục được lưu trữ có cùng một phần mã được lặp đi lặp lại trong suốt. Tôi nhận thấy vì tôi được giao nhiệm vụ thay đổi một phần nhỏ của mã đó trong mỗi SP mà nó xảy ra :)

Nó là một đoạn mã khá lớn, khoảng 30 dòng. Mã này là một phần của câu lệnh chèn và về cơ bản nó kết hợp 4 bảng với các WHERE/ANDđiều kiện không thực sự thay đổi từ SP sang SP. Nó trông tương tự như dưới đây:

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

Phần duy nhất thay đổi từ SP sang SP là các giá trị ( 'abc', 'def', 'ghi' )

Cũng có thể có số lượng khác nhau của các giá trị đó, vì vậy một số SP sẽ có 2 giá trị, một số khác sẽ có 5, v.v ...

Tất cả mọi thứ tôi nghĩ về việc thay đổi phần mã đó thành SQL động và tôi không chắc liệu điều đó có đáng không. Tuy nhiên, lập trình viên trong tôi ghét tình huống này.

Tôi có nên thử thực hiện một số hình thức tái sử dụng mã? Nó sẽ có ROI? Những lựa chọn của tôi là gì? Tôi đã phải trải qua ~ 100 thủ tục lưu trữ, mất khoảng một giờ.

100 SP được trải rộng trên 20 cơ sở dữ liệu khác nhau. Tôi có quyền để tạo ra một cái nhìn.

Câu trả lời:


11

Điều này sẽ làm việc cho bạn:

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

Sau đó thay thế trong Procs bằng:

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

Có cách nào để làm cho chế độ xem đơn lẻ đó lan truyền đến tất cả các cơ sở dữ liệu cần nó không?
Jeff.Clark

1
Các bảng có được nhân đôi trong 20 cơ sở dữ liệu không? Hoặc họ đang chọn từ các bảng trong một cơ sở dữ liệu?
Chad Mattox

Các bảng (cấu trúc) được nhân đôi trong 20 cơ sở dữ liệu đó. Các thủ tục được lưu trữ tương tự (thường sử dụng cùng một đoạn mã ở đây và đó) do tính chất của doanh nghiệp - Báo cáo EDI của Bảo hiểm y tế cho Obamacare. Mỗi cơ sở dữ liệu đại diện cho một công ty khác nhau, mỗi Quy trình được lưu trữ đại diện cho một Nhà cung cấp bảo hiểm khác nhau (Blue Cross / Kaiser / v.v ...)
Jeff.Clark

Sau đó, bạn cần phải nhân đôi chế độ xem cho mỗi cơ sở dữ liệu
Chad Mattox

2

Giải pháp này sẽ thay thế nhu cầu có hơn 100 procs làm điều tương tự. bạn có một Proc và một chức năng. Hàm chia tất cả các mã y tế của bạn từ một chuỗi thành một bảng có thể được sử dụng trong ỨNG DỤNG CROSS trong Proc mới. Bằng cách này, bạn chỉ phải gọi một Proc. Tất nhiên, bạn phải cập nhật tất cả các mã gọi các procs khác để sử dụng chỉ mã này.

--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 .....
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.