在Access VBA中向SQL Server存储过程传递空日期值问题
解决Access写入SQL Server时空日期变成1899-12-30的问题
问题根源
Access的日期控件空值/未输入时,默认会返回OLE自动化的“空日期”(#12/30/1899#),如果直接传递给SQL Server,会被存储为该日期而非NULL,你的现有代码没正确拦截这个默认值。
分步修改方案
1. 修正Access VBA参数传递代码
原来的代码用Format(CDate(Nz(!custi_birth_date, Empty)), "YYYY-MM-DD")会把空值强制转成1899-12-30的格式化字符串,反而传递了无效日期。改为直接判断空值,传递NULL:
' 先创建参数,不直接赋值 Dim birthParam As ADODB.Parameter Set birthParam = cmd.CreateParameter("@p_custi_birth_date", adDBTimeStamp, adParamInput) ' 判断控件值是否为空/默认空日期 If IsNull(!custi_birth_date) Or !custi_birth_date = #12/30/1899# Then birthParam.Value = Null Else birthParam.Value = CDate(!custi_birth_date) End If cmd.Parameters.Append birthParam
2. 调整SQL Server存储过程
存储过程里的NULLIF(@p_custi_birth_date, '')无效,因为datetime类型参数和空字符串无法匹配。改为直接接受NULL参数,或者拦截默认空日期转NULL:
方式一:允许参数为NULL(推荐)
确保存储过程参数定义允许NULL,直接写入参数值:
CREATE PROCEDURE 你的存储过程名 @p_custi_birth_date DATETIME = NULL -- 设为可选参数,默认NULL AS BEGIN SET NOCOUNT ON; INSERT INTO 客户表 (custi_birth_date) VALUES (@p_custi_birth_date); END
方式二:拦截默认空日期
如果必须处理传入的1899-12-30,用CASE判断转换:
CREATE PROCEDURE 你的存储过程名 @p_custi_birth_date DATETIME AS BEGIN SET NOCOUNT ON; INSERT INTO 客户表 (custi_birth_date) VALUES ( CASE WHEN @p_custi_birth_date = '1899-12-30' THEN NULL ELSE @p_custi_birth_date END ); END
3. 检查SQL Server表结构
确认客户表的custi_birth_date列设置为允许NULL,且没有设置默认值(如果默认值是1899-12-30会覆盖传入的NULL)。
内容的提问来源于stack exchange,提问作者A.J
相关产品推荐
相关产品推荐

