这让我摸不着头脑。有一个类似的问题可能与 "function does not exist," but I really think it does 和 PostgreSQL function does not exist 相关,但答案似乎不是很明显。 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<MembershipUser>().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;
...使用这些凭据,我可以看到函数:
然而,当我在我的 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]
我已经使用这个库一段时间了,但这是我第一次看到这条消息。有什么我想念的吗?
最佳答案
请注意,postgres 允许 function overloading ,因此不仅函数 NAME 需要存在,而且函数参数的类型也将用于确定要使用的重载,例如
CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, varchar, boolean)
不是一样的功能
CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, boolean, varchar)
等等。
调用这些函数时,参数名称、类型和可能的顺序必须全部匹配,否则你会得到
另一个让我头疼的问题是 Postgressql 在定义函数时的区分大小写规则。例如,没有任何周围的
""
引号,以下函数定义(使用 pgAdmin 3 中的默认设置):CREATE FUNCTION MySchema.MyFunction(Parameter1 VARCHAR(40), parameTer2 VARCHAR(20))
使用签名注册函数:(使用IDE工具验证这一点)
myschema.myfunction(parameter1 VARCHAR(40), parameter2 VARCHAR(20))
因此,在 C# 中任何尝试绑定(bind)到
command.Parameters.Add("Parameter1", NpgsqlDbType.Varchar, 40);
command.Parameters.Add("parameTer2", NpgsqlDbType.Varchar, 20);
将因错误而失败。相反,您需要绑定(bind)全小写参数,即
command.Parameters.Add("parameter1", NpgsqlDbType.Varchar, 40);
command.Parameters.Add("parameter2", NpgsqlDbType.Varchar, 20);
除非你用引号定义函数:
CREATE FUNCTION "MySchema"."MyFunction"("Parameter1" VARCHAR(40), "parameTer2" VARCHAR(20))
这就是为什么对您的数据库/组织中的大小写约定达成一致并坚持下去很重要的原因(all lowercase 很常见)
另一种选择,虽然也容易脆弱,但根本不绑定(bind)命名参数,而是使用参数的序数位置来绑定(bind)它,例如
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)
关于c# - Npgsql/Postgresql : "function does not exist" error message when it does,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44814675/