You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL使用CASE WHEN排序选emp_name时出现日期转换错误求助

解决动态排序时的类型转换错误

错误原因

问题出在CASE表达式的类型一致性上。SQL要求CASE所有分支返回的数据类型必须统一,你的CASE里同时返回数值型(REQUESTING_AMOUNT)、字符串型(EMP_FULLNAME)、日期型(BET_APPLY_DATE)三种类型,SQL会自动按类型优先级(日期>数值>字符串)做隐式转换。当选择emp_name作为排序字段时,SQL尝试把字符串转成日期类型,就触发了Conversion failed when converting date and/or time from character string错误。

解决方案

方案1:拆分CASE表达式,确保类型一致

将ORDER BY子句拆分为多个CASE,每个CASE仅对应一个排序字段,保证每个分支返回的类型与对应字段一致,避免强制转换。同时合并重复的查询逻辑,简化代码:

DECLARE @srch_text varchar(50) = 'Cha'
DECLARE @page_no int = 1
DECLARE @page_size int = 10
DECLARE @sort_column  varchar(50) = 'emp_name'
DECLARE @order varchar(50) = 'ASC'

SELECT 
    i.TRN_ID,
    e.EMP_FULLNAME,
    i.REQUESTING_AMOUNT,
    i.BET_APPLY_DATE 
FROM INTERMEDIATE i
INNER JOIN EMPLOYEE e ON i.BET_EMP_NUMBER = e.EMP_NUMBER 
WHERE e.EMP_FULLNAME LIKE '%' + @srch_text + '%'
ORDER BY 
    -- 按排序字段和方向分别处理,保证类型匹配
    CASE WHEN @sort_column = 'req_amount' AND @order = 'ASC' THEN i.REQUESTING_AMOUNT END ASC,
    CASE WHEN @sort_column = 'req_amount' AND @order = 'DESC' THEN i.REQUESTING_AMOUNT END DESC,
    CASE WHEN @sort_column = 'emp_name' AND @order = 'ASC' THEN e.EMP_FULLNAME END ASC,
    CASE WHEN @sort_column = 'emp_name' AND @order = 'DESC' THEN e.EMP_FULLNAME END DESC,
    CASE WHEN @sort_column = 'apply_date' AND @order = 'ASC' THEN i.BET_APPLY_DATE END ASC,
    CASE WHEN @sort_column = 'apply_date' AND @order = 'DESC' THEN i.BET_APPLY_DATE END DESC
OFFSET @page_size * (@page_no - 1) ROWS 
FETCH NEXT @page_size ROWS ONLY

方案2:使用动态SQL(需防范注入风险)

如果觉得拆分CASE过于繁琐,可以用动态SQL拼接排序逻辑,通过参数化查询避免SQL注入:

DECLARE @srch_text varchar(50) = 'Cha'
DECLARE @page_no int = 1
DECLARE @page_size int = 10
DECLARE @sort_column  varchar(50) = 'emp_name'
DECLARE @order varchar(50) = 'ASC'
DECLARE @sql nvarchar(max)
DECLARE @params nvarchar(max)

-- 验证排序字段和方向的合法性,防止恶意注入
IF @sort_column NOT IN ('req_amount', 'emp_name', 'apply_date')
    SET @sort_column = 'emp_name'
IF @order NOT IN ('ASC', 'DESC')
    SET @order = 'ASC'

-- 映射前端字段名到实际表列
DECLARE @sort_col_real varchar(50)
SELECT @sort_col_real = CASE 
    WHEN @sort_column = 'req_amount' THEN 'i.REQUESTING_AMOUNT'
    WHEN @sort_column = 'emp_name' THEN 'e.EMP_FULLNAME'
    WHEN @sort_column = 'apply_date' THEN 'i.BET_APPLY_DATE'
END

SET @sql = N'
SELECT 
    i.TRN_ID,
    e.EMP_FULLNAME,
    i.REQUESTING_AMOUNT,
    i.BET_APPLY_DATE 
FROM INTERMEDIATE i
INNER JOIN EMPLOYEE e ON i.BET_EMP_NUMBER = e.EMP_NUMBER 
WHERE e.EMP_FULLNAME LIKE ''%'' + @srch_text + ''%''
ORDER BY ' + @sort_col_real + ' ' + @order + '
OFFSET @page_size * (@page_no - 1) ROWS 
FETCH NEXT @page_size ROWS ONLY'

SET @params = N'@srch_text varchar(50), @page_no int, @page_size int'

EXEC sp_executesql @sql, @params, 
    @srch_text = @srch_text, 
    @page_no = @page_no, 
    @page_size = @page_size

内容的提问来源于stack exchange,提问作者hotflix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 19:15:06