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

使用EF Core调用PostgreSQL存储过程报42883错误的求助

PostgreSQL存储过程调用问题排查与解决思路

问题背景

在ASP.NET Core 8.0 MVC项目中,使用EF Core 8.0.5调用PostgreSQL存储过程时触发错误,提示存储过程不存在,但该存储过程已创建且在DBeaver中可正常查看。

存储过程定义

CREATE OR REPLACE PROCEDURE gselogwebsite_add
(
    _logUserId INT,
    _logSourceId INT,
    _logCat INT,
    _logLevel INT,
    _logType INT,
    _logText TEXT,
    _logDateTimeUTC TIMESTAMP WITHOUT TIME ZONE,
    INOUT _logId BIGINT
)
LANGUAGE plpgsql AS
$BODY$
BEGIN
    ...
    ... 
    ...
END;
$BODY$;

调用代码

context.Database.ExecuteSqlRaw("CALL gselogwebsite_add(@_logUserId, @_logSourceId, @_logCat, @_logLevel, @_logType, @_logText, @_logDateTimeUTC, @_logId)", 
    new NpgsqlParameter("_logUserId", logUserId),
    new NpgsqlParameter("_logSourceId", logSourceId),
    new NpgsqlParameter("_logCat", logCat),
    new NpgsqlParameter("_logLevel", logLevel),
    new NpgsqlParameter("_logType", logType),
    new NpgsqlParameter("_logText", logText),
    new NpgsqlParameter("_logDateTimeUTC", logDateTimeUTC),
    new NpgsqlParameter("_logId", DBNull.Value) { DbType = DbType.Int64, Direction = ParameterDirection.InputOutput }
);

错误信息

Npgsql.PostgresException: '42883: procedure gselogwebsite_add(integer, integer, integer, integer, integer, text, timestamp with time zone, bigint) does not exist

解决思路

  • 修正时区参数类型:错误提示显示_logDateTimeUTC被识别为timestamp with time zone,但存储过程定义是TIMESTAMP WITHOUT TIME ZONE。需显式指定参数类型为TimestampWithoutTimeZone:

    new NpgsqlParameter("_logDateTimeUTC", NpgsqlDbType.TimestampWithoutTimeZone) { Value = logDateTimeUTC }
    
  • 指定存储过程架构:确认存储过程所在架构(默认通常为public),调用时添加架构前缀,避免因架构匹配失败导致找不到存储过程:

    context.Database.ExecuteSqlRaw("CALL public.gselogwebsite_add(...)", ...);
    
  • 验证参数顺序与权限:PostgreSQL对存储过程的参数顺序要求严格,确保调用时参数顺序与定义完全一致;同时检查数据库连接用户是否拥有该存储过程的EXECUTE权限。

  • 优化输入输出参数定义:显式指定_logId的Npgsql类型,确保EF Core正确识别INOUT参数:

    new NpgsqlParameter("_logId", NpgsqlDbType.Bigint) { Value = DBNull.Value, Direction = ParameterDirection.InputOutput }
    
  • 尝试异步调用方式:替换为ExecuteSqlAsync异步方法,确保参数传递逻辑一致,排查同步调用可能存在的隐性问题:

    await context.Database.ExecuteSqlAsync("CALL public.gselogwebsite_add(@_logUserId, @_logSourceId, @_logCat, @_logLevel, @_logType, @_logText, @_logDateTimeUTC, @_logId)", 
        new NpgsqlParameter("_logUserId", logUserId),
        new NpgsqlParameter("_logSourceId", logSourceId),
        new NpgsqlParameter("_logCat", logCat),
        new NpgsqlParameter("_logLevel", logLevel),
        new NpgsqlParameter("_logType", logType),
        new NpgsqlParameter("_logText", logText),
        new NpgsqlParameter("_logDateTimeUTC", NpgsqlDbType.TimestampWithoutTimeZone) { Value = logDateTimeUTC },
        new NpgsqlParameter("_logId", NpgsqlDbType.Bigint) { Value = DBNull.Value, Direction = ParameterDirection.InputOutput }
    );
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:53:12