這是我的存儲過程來搜索用戶上傳圖片的畫廊:動態ORDER BY在存儲過程中不能按預期工作
ALTER PROCEDURE dbo.sp_SearchGallery
(
@strSearchTerm NVARCHAR(50) = NULL,
@strCategory NVARCHAR(50) = NULL,
@nUserId INT = NULL,
@nSortBy INT = 0,
@nSortDesc BIT = 0,
@nPage INT = 1,
@nPageSize INT = 10
) AS
SET NOCOUNT ON
DECLARE @nSortSwitch INT = 1
IF @nSortDesc = 1 BEGIN
SET @nSortSwitch = -1
END
DECLARE @FirstRec INT = (@nPage - 1) * @nPageSize
DECLARE @LastRec INT = (@nPage * @nPageSize + 1)
; WITH rowQueryResults AS
(
SELECT *, ROW_NUMBER() OVER
(
ORDER BY
CASE @nSortBy
WHEN 0 THEN Date
WHEN 1 THEN Title
WHEN 2 THEN Description
WHEN 3 THEN ID
END
) AS RowNum
FROM dbo.GalleryItems
WHERE ((@strSearchTerm IS NULL OR Title LIKE '%' + @strSearchTerm + '%') OR
(@strSearchTerm IS NULL OR Description LIKE '%' + @strSearchTerm + '%')) AND
(@nUserId IS NULL OR UserId = @nUserId) AND
(@strCategory IS NULL OR Category LIKE '%' + @strCategory + '%') AND
(Accepted=1)
)
SELECT *
FROM rowQueryResults
WHERE RowNum > @FirstRec AND RowNum < @LastRec
ORDER BY RowNum*@nSortSwitch
RETURN
我可以設置@nSortBy
爲0,這工作正常。我可以將其設置爲3,這也正常,但只要我把它設置爲1或2,其不同之處崩潰Conversion failed when converting date and/or time from character string.
什麼我假設是它試圖將Title
或Description
轉換爲DateTime
訂購。 ID
之所以能夠工作,是因爲它是一個Integer,因此可以安全地轉換爲DateTime(顯然,這不是我想要它做的)
但是,它爲什麼要這麼做呢?我如何做到這一點,所以它做了一個strcmp而不是一個時間比較訂購?
「爲什麼會這樣做? - 因爲'CASE'是*表達式*。它產生一個值。因此它有一個數據類型。給定THEN條款中的所有表達式,它會考慮所有數據類型,應用適當的優先規則並確定表達式的整體類型。請記住,*一般情況下*不能保證'CASE'表達式只會爲*所有行*輸入一個單獨的THEN'子句(例如,它被定義爲用於多於常量表達式) –
另外,注意 - ['CREATE PROCEDURE'](https://msdn.microsoft.com/zh-CN/library/ms187926.aspx) - 「避免在命名過程中使用** sp _ **前綴。此前綴由SQL使用服務器來指定系統過程。「 –
@Damien_The_Unbeliever - 謝謝你的回答。我現在完全明白了。我會改名字:) – Andy