2009-04-27 145 views
2

我正在處理這個例子。如何運行查詢以使用參數對列和asc/desc進行排序?

http://www.drury.net.nz/2005/04/15/specifying-a-sort-parameter-for-a-tsql-stored-procedure/

CREATE PROCEDURE getEmployees (@ColumnName varchar(100)) 
AS 
    SELECT 
    EmployeeID, 
    FirstName, 
    LastName, 
    SSN, 
    Salary 
    FROM 
    Employees 
    ORDER BY 
    CASE 
     WHEN @ColumnName=’LastName’ THEN LastName 
     WHEN @ColumnName=’Salary’ THEN CONVERT(varchar(50), Salary) 
     WHEN @ColumnName=’SSN’ THEN SSN 
    END 

case語句的作品,但如果我有以下參數:@SortColumn,@SortDirection。

@SortColumn可以是任何類型的任何列,它似乎使用case語句,您必須將值轉換爲相同的類型。我想我可以讓它們都成爲VARCHAR,並且只要確保像DateTime這樣的值按正確的順序放置就可以按我的意願排序。

但是如果我將@SortDirection參數設置爲ASC或DESC作爲VARCHAR值怎麼辦?如何調整查詢以改變排序方向?

回答

4

如果你不想使用動態SQL,那麼你可以這樣做,通過使case語句導致where子句的非過濾部分;它不會很快。您還需要小心您的病例部分中的類型是否匹配。

SELECT 
    * 
FROM 
    dbo.Contacts 
ORDER BY 
    CASE @Sort 
     WHEN 1 THEN Surname 
     WHEN 2 THEN Forename 
     WHEN 3 THEN Telephone_Number 
     ELSE  '' 
    END ASC 
    , 
    CASE @Sort 
     WHEN 4 THEN Personnel_Ref 
     WHEN 5 THEN timesheet_number 
     WHEN 6 THEN Telephone_Number 
     ELSE  '' 
    END DESC 
0

您可以使用動態查詢。

舉一個例子,看看here

+0

我已經考慮動態查詢,但我正在盡我所能避免它們。我曾經看到我可以使用參數進行排序,但我不記得如何完成這項工作。 – Brennan 2009-04-27 23:45:38

+0

你應該儘可能避免動態查詢或遊標。 – Sung 2009-04-28 02:47:16

0

我覺得你的詩情會是這樣的:

如果你有

@SortColumn varchar(50), @SortDirection varchar(50) 

,那麼你可以這樣做:

DECLARE @sql nvarchar(4000)  
SET @sql = N'SELECT EmployeeID, FirstName, LastName, SSN, Salary ' + 
      'FROM Employees ' + 
      'ORDER BY ' + @SortColumn + ' ' + @SortDirection  
EXEC sp_executesql @sql 

當然,你可以在存儲過程中放或任何你想要的。

+0

你知道我如何避免使用sp_executesql嗎?我聽說如果你使用它,那麼它不能緩存查詢計劃。 – Brennan 2009-04-28 00:16:03

0

Employee表的select語句的結果放入表變量或臨時表中。

然後使用if..else語句返回結果升序/降序。

使用if..else沒有任何問題。

1

(我沒有足夠的聲譽顯然發表評論,所以我回答在這裏)

在回答:

你知道我怎麼能避免使用sp_executesql的?我聽說如果你使用 那麼它不能緩存查詢計劃。 - Brennan 4月28日0:16

實際上,在大多數情況下,sp_executesql允許將查詢計劃緩存爲與存儲過程相同。

的訣竅是使用參數化動態SQL,像這樣:

exec sp_executesql N'select from MyTable where myId = @id', N'@id int', @id; 

這樣,你正在運行相同的查詢,只需在@id替代,就像使用存儲過程。通過動態sql,查詢計劃將基於查詢的字符串值(sp_executesql的第一個參數)進行緩存。

我想問的唯一問題是爲什麼你必須在數據庫中對此進行排序?我覺得你應該稍後對它進行排序......

但是,由於排序表達式和方向不能被參數化(它們必須連接到查詢字符串中),因此您將獲得單獨的查詢計劃緩存爲每一種排序表達和方向。這可能不是什麼大不了的事情。

編輯: 下面是解釋如何dynamic SQL query plans are cached

相關問題