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

C#调用PostgreSQL存储过程:无时区timestamp参数处理

解决C#调用PostgreSQL存储过程的参数类型不匹配问题

报错No procedure matches the given name and argument types的核心原因是:PostgreSQL存储过程定义的参数是无时区的timestamp(TIMESTAMP),但C#中DateTime对象默认会被Npgsql驱动转换为**带时区的timestamp(TIMESTAMPTZ)**传入,导致类型不匹配。

下面提供三种可行的解决方式:

方式一:修改存储过程参数类型(最简单)

直接把存储过程的参数类型改为TIMESTAMPTZ,和C#传入的类型对齐:

CREATE OR REPLACE PROCEDURE get_documents(  
    p_issue_date TIMESTAMPTZ
)
language plpgsql
as $$
begin   
    select * from documents ;
end; $$;

这种方式不需要修改任何C#代码,适合不需要严格区分无时区时间的场景。

方式二:在C#中显式指定参数类型

通过Npgsql的参数类型指定,将DateTime转换为无时区的TIMESTAMP:

using System.Data; // 需引用此命名空间使用CommandType

var parameters = new[]
{
    new NpgsqlParameter("p_issue_date", NpgsqlDbType.Timestamp)
    {
        Value = input.Date
    }
};

var test2 = await _dbContext.QueryAsync<Documents>(
    "get_documents", 
    parameters, 
    commandType: CommandType.StoredProcedure
);

这种方式适合需要保留存储过程参数类型不变的场景,精准控制单个参数的类型映射。

如果项目中大量场景需要将DateTime映射为无时区TIMESTAMP,可以全局配置Npgsql的类型映射(在项目启动时执行一次即可):

NpgsqlConnection.GlobalTypeMapper.MapDateTime(DateTimeMapping.Timestamp);

方式三:在存储过程内部转换参数类型

保持存储过程参数类型不变,在内部将带时区的参数转换为无时区的TIMESTAMP:

CREATE OR REPLACE PROCEDURE get_documents(  
    p_issue_date TIMESTAMPTZ
)
language plpgsql
as $$
begin   
    -- 转换为无时区timestamp,注意时区转换逻辑需符合业务需求
    select * from documents where issue_date = p_issue_date::TIMESTAMP;
end; $$;

注意:这种方式需要确认时区转换后的时间符合业务逻辑,避免出现时间偏差问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 07:15:26