我們當前正在使用SQL server 2016.基於微軟頁面Deprecated Database Engine Features in SQL Server 2016,SET ROWCOUNT
已被棄用。所以我們試圖將所有SET ROWCOUNT N
報表轉換爲TOP(N)
報表。看起來很容易,但我們遇到了一個情況,其中N是存儲過程中的一個參數,默認爲0.當n可能爲0時,將SET ROWCOUNT n轉換爲TOP(n)
因此在舊代碼中,它類似於SET ROWCOUNT @NumRows
。如果@NumRows
爲0,則表示關閉SET ROWCOUNT
選項,因此以下查詢將返回所有行。但是如果我們將其轉換爲TOP(@NumRows)
,那意味着它將返回0行。爲了避免這個問題,我們可以添加額外的IF條件,如果@NumRows
爲0,則將@NumRows
設置爲一個很大的數字。或者我們可以添加額外的IF條件,如果@NumRows
爲0,那麼我們使用SELECT沒有TOP,否則我們像往常一樣做SELECT TOP(N)
。
但是這些解決方案中的任何一個都會在存儲過程中添加額外的代碼,所以我的問題是:考慮到N可能爲0,是否有一種將SET ROWCOUNT N
轉換爲TOP (N)
的優雅方法?
更新:增加了存儲過程模板
-- Default to 0, in this case, SET ROWCOUNT 0 will return all result
-- But if we change it to TOP(@rows), it returns no result.
CREATE PROCEDURE Proc1
@rows int = 0
AS
SET ROWCOUNT @rows
SELECT Col1 FROM table1
ORDER BY Col2
SET ROWCOUNT 0
-- In this case, the default is not 0
-- But the program that calls this stored procedure could pass in value 0.
-- We also don't want to change default value for this stored procedure.
-- So I think in this case, we may have to add IF @rows = 0, SET @rows = huge_number
CREATE PROCEDURE Proc2
@rows int = 10
AS
SET ROWCOUNT @rows
SELECT Col3 FROM table2
ORDER BY Col4
SET ROWCOUNT 0
優雅?但是,在插入到你的'top'子句之前,你可以說'選擇@NumRows = iif(@NumRows = 0,2147483648,@NumRows)'。這就是說,這可能會給你很糟糕的查詢計劃。除非您有數千個程序需要查找/替換,否則您可能需要考慮指定兩個不同代碼路徑的額外工作。你的旅費可能會改變。 – Xedni
我會警告不要使用多個執行路徑。它可能會導致非常有趣的性能問題。 Gail Shaw在這裏有一個很棒的博客文章。 http://www.sqlinthewild.co.za/index.php/2009/09/15/multiple-execution-paths/ –
@SeanLange感謝您的鏈接。我通讀了它並理解不同執行計劃的可能性。所以如果我不使用不同的執行路徑,那意味着我總是使用'TOP(N)'。然後我需要檢查N值是否爲0。如果它是0,我可以從表中'NumRows' = 2147483647或'NumRows' = count(*),這對查詢計劃有什麼影響? – Dongminator