使用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
相关产品推荐
相关产品推荐

