我最近在工作中被問到要執行許多SQL Server存儲過程「適應」。我可以管理,但我主要是一個.Net開發人員,所以我不知道什麼是好的做法,或者是否有更好的方法來做事情。有多個可選參數的存儲過程
簡而言之,就是這種情況。我們有許多腳本每晚運行以避免對生產造成任何影響。他們掃描多個數據庫(鏈接服務器和所有)以查找特殊情況並在發現這種情況時添加記錄。每個腳本都會在所有數據庫(包含數百萬條記錄)上執行此操作,並且有超過一百個以這種方式運行的腳本。
現在,我被要求更改這些腳本,以便他們可以接受參數並被稱爲「按需」(不再需要每晚運行)。簡單。
我在哪裏,猶豫,是他們希望調用SAME過程,但對於不同的場景,每個場景都會傳遞它自己的一組參數,然後查詢應該執行一些業務邏輯去執行那個特定的「場景」。
例如,存儲過程將具有這些輸入參數定義:
@PersonId, @OrderId, @OrderType, @RequestCode, ....
和可能更多一些。
當存儲過程收到@PersonId
時,我應該返回該人的所有特殊情況,但如果是@OrderType
,那應該是所有情況,但是對於該特定類型。但是,如果它收到OrderId
,存儲過程應該返回該訂單的所有特殊情況。如果提供了RequestCode
,它應該返回與該代碼關聯的所有情況,針對每個人,所有要求。有4個場景需要處理,它們都應該返回相同的數據,但是針對不同的條件。
他們特別要求應該只有一個腳本(每個特殊情況)來處理所有可能性。
就像我說的那樣,現在腳本每晚都運行,整個數據庫沒有參數。
我建議將腳本轉換爲代碼,這樣我就可以使用所有好的模式,添加測試,隔離它們以及所有內容。如果我保留「sql方式」,我很害怕每一個小小的變化都意味着更多的測試,並且由於我們可以輕鬆訪問程序員,但是數據庫管理員是非常罕見的,有特殊情況按需檢測.NET(這是檢測請求將被調用的地方......),擁有一些類和接口應該更容易維護和發展,即使是初級。
請求不再運行在每條記錄上,並且沒有那麼多員工會提出這些請求,尤其是那些請求不會同時發生。所以我也沒有看到性能問題?
我是一名開發人員,所以我當然偏向於。但是,如果有一種很好的方式來滿足他們對我的要求(將所有內容保存在存儲過程中,有許多參數,條件和明顯的某種程度的業務邏輯),我也可以做得更好。
對不起,對於這篇較長的文章,特別感謝那些有時間留意一些建議的人!
編輯:假設我改編腳本以處理所有可能性,測試的主要影響是什麼,可以預見的可維護性是什麼?由於我沒有經驗,我認爲,對於這樣一個「可以做任何事情的魔術腳本」,調試,測試和一切都將是一場噩夢,但這裏的人們似乎忽略了它。但他們不是程序員,也不是數據庫管理員,所以我想提出一些理由,讓他們按照正確的方式做事情,無論是現在還是將來,即使這意味着開始時會有更高的成本。謝謝!
讓單個存儲過程完成不同的事情是非常糟糕的設計。這就像在dotnet中創建一個方法,根據傳遞的參數完成不同的操作。就像你的編程代碼一樣,你希望你的程序做一件事,做得很好。 –
我完全同意。我試圖從有經驗的數據庫管理員那裏得到很好的建議,所以我們可以提出一些要點,以便我們能夠很好地解決如何管理這些問題。謝謝。 –
這可以歸結爲性能。將爲存儲過程創建一個執行計劃並存儲在緩存中。當你有多個像這樣的執行路徑時,它會完全破壞引擎一致性生成高效執行計劃的能力。所以即使這個計劃對於一組參數來說很好,但對另一個參數來說也是可怕的。但是,如果它存在,它將使用已存在於高速緩存中的計劃。如果有什麼可以創建一個程序作爲「驅動程序」,並讓它根據參數調用各種其他程序。這爲每條路徑提供了一個很好的計劃。 –