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

在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:42:31