这是我搜索用户上传的图片库的存储过程:
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
之所以有效,是因为它是一个整数,因此可以安全地转换为DateTime(显然不是我想要它做的事)
但是,为什么会那样做呢?我怎么做它所以它做一个strcmp而不是时间比较订购?
答案 0 :(得分:3)
这与数据优先级有关,当您遇到不同数据类型之间的情况时,SQL会将较低数据类型转换为最高数据类型。尝试这样,以便您的最高数据类型变为varchar,因此它不会尝试将标题和描述转换为日期时间。
ORDER BY
CASE @nSortBy
WHEN 0 THEN convert(varchar, Date)
WHEN 1 THEN Title
WHEN 2 THEN Description
WHEN 3 THEN convert(varchar, ID)
END
答案 1 :(得分:3)
有一个简单的替代方案,不需要转换:
ORDER BY
CASE WHEN @nSortBy = 0 THEN Date END,
CASE WHEN @nSortBy = 1 THEN Title END,
CASE WHEN @nSortBy = 2 THEN Description END,
CASE WHEN @nSortBy = 3 THEN ID END
这是一个奇怪的小技巧。从理论上讲,它按排名顺序在四个字段上进行ORDER BY。实际上虽然@nSortBy只能有一个值,所以实际上只对其中的四个排序中的一个进行了操作。