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

存储过程中CONVERT转换datetime在Report Builder运行时转换失败问题

问题原因
  1. 日期转换格式不匹配:当前使用的转换格式码101对应mm/dd/yyyy格式的字符串,而EZ.ACDT、EZ.TRDT字段大概率是8位数字类型(INT、DECIMAL等)存储的YYYYMMDD格式日期,转CHAR(8)后得到的是YYYYMMDD格式字符串,匹配的正确转换格式码应为112。之前其他存储过程未报错,多是因为执行顺序先过滤掉了不符合预期的数据,或旧执行计划刚好避开了错误数据的转换逻辑。
  2. 执行计划计算顺序差异:存储过程本地直接执行和Report Builder调用时生成的执行计划不同,当前存储过程中WHERE条件的日期转换操作可能先于deleted='N'、CONO='100'等基础过滤条件执行,提前接触到空值、非8位非法值等脏数据就会触发报错。
  3. 隐式类型转换冲突:Report Builder传参时可能存在参数的隐式类型转换,和存储过程里转换后的datetime类型匹配时触发额外转换逻辑,放大了格式不匹配的问题。
解决方案
  • 修正日期转换格式码
    把所有CONVERT(datetime, CONVERT(CHAR(8), EZ.ACDT), 101)、CONVERT(datetime, CONVERT(CHAR(8), EZ.TRDT), 101)中的格式码从101改为112,112是YYYYMMDD格式字符串转日期的标准格式码,适配8位数字存储的日期字段。
    修改后示例:
    CONVERT(datetime, CONVERT(CHAR(8), EZ.ACDT), 112) as 'ACCOUNTING DATE'

  • 使用安全转换函数避免报错(适用SQL Server 2012及以上版本)
    把CONVERT替换为TRY_CONVERT,转换失败时会返回NULL而不是直接抛出中断错误,也可以配合过滤条件排除转换失败的非法数据:
    示例:
    TRY_CONVERT(datetime, CONVERT(CHAR(8), EZ.ACDT), 112) as 'ACCOUNTING DATE'
    WHERE条件同步替换即可:
    AND TRY_CONVERT(datetime, CONVERT(CHAR(8), EZ.ACDT), 112) BETWEEN @FROMACCDATE AND @TOACCDATE

  • 调整过滤优先级提前筛除脏数据
    可以用CTE先取出符合基础过滤条件的数据集,再做日期转换和后续过滤,避免转换操作接触到脏数据,参考修改逻辑:

ALTER PROCEDURE [dbo].[RPT_CAS300_REPORT]
(
@DIVISION NVARCHAR(50)
,@FROMACCDATE date
,@TOACCDATE date
,@FROMTRANSDATE date
,@TOTRANSDATE date
,@ERRORCODE NVARCHAR(50)
)
AS
BEGIN
WITH ValidCINACC AS (
    SELECT * FROM CINACC
    WHERE CONO = '100' 
    AND deleted = 'N'
    AND ISNULL(ACDT,0) > 0 
    AND LEN(CONVERT(CHAR(8), ACDT)) = 8
    AND ISNULL(TRDT,0) > 0 
    AND LEN(CONVERT(CHAR(8), TRDT)) = 8
)
select distinct
EZ.DIVI AS 'DIVISION',
EZ.ANBR AS 'ACCOUNT NUMBER',
EZ.SENO AS 'SEQ NO',
EZ.EVEN AS 'EVENT',
CONVERT(datetime, CONVERT(CHAR(8), EZ.ACDT), 112) as 'ACCOUNTING DATE',
CONVERT(datetime, CONVERT(CHAR(8), EZ.TRDT), 112) AS 'TRANSACTION DATE',
EZ.ACTY AS 'ACCOUNT TYPE',
EZ.ITNO AS 'ITEM NUMBER',
MM.ITDS AS 'STYLE',
MM.BUAR AS 'BRAND',
MM.ITGR AS 'CLASS',
EZ.ACQT AS 'QUANTITY',
EZ.ACAM AS 'RECORDED AMOUNT',
EZ.AIT1 AS 'DIM 1: GL',
EA.TX40 AS 'GL DESCRIPTION',
EZ.AIT2 AS 'DIM 2: COST CENTRE',
EZ.AIT3 AS 'DIM 3: BRAND',
EZ.AIT4 AS 'DIM 4: CHANNEL',
EZ.AIT5 AS 'DIM 5: WAREHOUSE',
EZ.AIT6 AS 'DIM 6: ORDER',
EZ.AIT7 AS 'DIM 7: ACCOUNTING RULE',
EZ.RGDT AS 'END DATE',
EZ.ERCD AS 'ERROR CODE'
from ValidCINACC EZ
left join MITMAS MM on MM.CONO = EZ.CONO
    and MM.ITNO = EZ.ITNO
left join FCHACC EA on EA.CONO = EZ.CONO
    and EA.AITM = EZ.AIT1
where 
    (EZ.DIVI IN ( SELECT Value FROM dbo.FnSplit( @DIVISION,',') ) OR @DIVISION IS NULL ) 
    AND (EZ.ERCD IN ( SELECT Value FROM dbo.FnSplit( @ERRORCODE,',') ) OR @ERRORCODE IS NULL ) 
    AND CONVERT(datetime, CONVERT(CHAR(8), EZ.ACDT), 112) BETWEEN @FROMACCDATE AND @TOACCDATE
    AND CONVERT(datetime, CONVERT(CHAR(8), EZ.TRDT), 112) BETWEEN @FROMTRANSDATE AND @TOTRANSDATE
END
  • 低版本SQL Server兼容方案
    如果使用的SQL Server版本不支持TRY_CONVERT,可以先执行以下查询找出表中的非法日期值,清理脏数据后即可解决报错:
SELECT ACDT, TRDT FROM CINACC 
WHERE deleted = 'N' AND CONO = '100'
AND (ISDATE(CONVERT(CHAR(8), ACDT), 112) = 0 OR ISDATE(CONVERT(CHAR(8), TRDT), 112) =0)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 04:39:00