Npgsql / Postgresql:“函数不存在”时出现错误信息

抓住我的头。 有一个类似的问题可能与“函数不存在”有关,但我真的认为它确实 存在并且PostgreSQL函数不存在,但答案似乎并不十分明显。 PostgreSQL 9.5。

我有一个基于Npgsql的成员资格查询,如下所示:

using (var conn = new NpgsqlConnection(ConnectionString)) { conn.Open(); using (var comm = new NpgsqlCommand("get_user_by_username", conn)) { comm.CommandType = CommandType.StoredProcedure; comm.Parameters.Add("_user_name", NpgsqlDbType.Varchar, 250).Value = username; comm.Parameters.Add("_application_name", NpgsqlDbType.Varchar, 250).Value = _ApplicationName; comm.Parameters.Add("_online", NpgsqlDbType.Boolean).Value = userIsOnline; using (var reader = comm.ExecuteReader()) { return GetUsersFromReader(reader).OfType().FirstOrDefault(); } } } 

这个函数存在于我的postgresql数据库中:

 CREATE OR REPLACE FUNCTION public.get_user_by_username( _user_name character varying, _application_name character varying, _online boolean) RETURNS SETOF user_record AS $BODY$begin if _online then return query update users set last_activity = current_timestamp where lower(application_name) = lower(_application_name) and lower(user_name) = lower(_user_name) returning user_id, user_name, last_activity, created, email, approved, last_lockout, last_login, last_password_changed, password_question, comment; else return query select user_id, user_name, last_activity, created, email, approved, last_lockout, last_login, last_password_changed, password_question, comment from users where lower(application_name) = lower(_application_name) and lower(user_name) = lower(_user_name); end if; end; $BODY$ LANGUAGE plpgsql VOLATILE COST 100 ROWS 1000; ALTER FUNCTION public.get_user_by_username(character varying, character varying, boolean) OWNER TO (configured db login); 

我已经检查,仔细检查并对连接字符串进行三重检查…它指向此数据库,并正确登录。 该函数从pgAdmin窗口执行正常。

我的连接字符串类似于:

 Server=localhost;Port=5432;Database=mysecuritydb;User Id=(configured db login);Password=(my password);Pooling=true;ConvertInfinityDateTime=true; 

…使用这些凭据,我可以看到function: 在此处输入图像描述

然而,当我在我的asp.net项目中使用它作为引用库时,我收到以下消息:

 Server Error in '/' Application. 42883: function get_user_by_username(_user_name => character varying, _application_name => character varying, online => boolean) does not exist Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: Npgsql.PostgresException: 42883: function get_user_by_username(_user_name => character varying, _application_name => character varying, online => boolean) does not exist Source Error: An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. Stack Trace: [PostgresException (0x80004005): 42883: function get_user_by_username(_user_name => character varying, _application_name => character varying, online => boolean) does not exist] 

我已经使用过这个库了一段时间,但这是我第一次看到这个消息。 有什么我想念的吗?

一个额外的陷阱,一直咬我

Npgsql.PostgresException:42883:函数不存在

是定义函数时的区分大小写规则。 例如,没有任何周围的""引号,以下定义:

 CREATE FUNCTION MySchema.MyFunction(Parameter1 VARCHAR(40), parameTer2 VARCHAR(20)) 

似乎实际上使用签名注册函数:(使用IDE工具来validation这一点)

 myschema.myfunction(parameter1 VARCHAR(40), parameter2 VARCHAR(20)) 

因此,任何C#绑定的尝试

 command.Parameters.Add("Parameter1", NpgsqlDbType.Varchar, 40); command.Parameters.Add("parameTer2", NpgsqlDbType.Varchar, 20); 

将失败并出现错误。 相反,您需要绑定全小写参数,即

 command.Parameters.Add("parameter1", NpgsqlDbType.Varchar, 40); command.Parameters.Add("parameter2", NpgsqlDbType.Varchar, 20); 

除非您使用引号定义函数:

 CREATE FUNCTION "MySchema"."MyFunction"("Parameter1" VARCHAR(40), "parameTer2" VARCHAR(20)) 

另一种方法是根本不与命名参数绑定,而是使用参数的序号位置来绑定它,例如

 var myParameter = new NpgsqlParameter { // Leave `ParameterName` out entirely, Direction = ParameterDirection.Input, IsNullable = false, NpgsqlDbType = NpgsqlDbType.Varchar, Size = 20, Value = "SomeValue" }; command.Parameters.Add(myParameter); // Same for other parameter(s) 

所以@JGH发现错误消息中的签名变量名在库中与发布的代码略有不同……这应该不会发生,但是我下拉了源代码,将其编译为依赖项目,一切都很好。 所以,预编译的库有问题,我可以解决它。

谢谢您的帮助!