Npgsql/ Postgresql。"函数不存在 "的错误信息,当它存在时[英] Npgsql/ Postgresql: "function does not exist" error message when it does

本文是小编为大家收集整理的关于Npgsql/ Postgresql。"函数不存在 "的错误信息,当它存在时的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

挠我的头.在上,也可能有类似的问题.不存在,"但是我真的认为它确实 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<MembershipUser>().FirstOrDefault();
        }
    }
}

此功能存在于我的PostgreSQL db中:

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);

我已经检查,仔细检查和三个检查了连接字符串...它指向此DB,并使用正确的登录.该函数从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]

我已经使用了一段时间,但这是我第一次看到此消息.我缺少什么吗?

推荐答案

因此,@jgh抓住了一个事实,即错误消息中的签名变量名称与已发布的代码中的片段略有不同……但这应该没有发生,但是我拉下了源代码,将其编译为一个依赖项目,一切正常.因此,预编译的库有一个问题,我可以解决它.

感谢您的帮助!

其他推荐答案

请注意,Postgres允许函数杂货仅需要存在函数名称,但是功能参数的类型也将用于确定要使用哪种过载,例如.

CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, varchar, boolean)   

的功能不同
CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, boolean, varchar)

等.

调用这些功能时,参数名称,类型和可能的订单都必须匹配,否则您将获得

npgsql.postgresexception:42883:函数不存在

在定义函数时,GostGressQL的病例敏感性规则是不断咬我的另外一个陷阱.例如,没有任何周围的""引号,以下函数定义(使用pgadmin 3中的默认设置):

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

用签名注册该功能:(使用IDE工具对此进行验证)

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))

这就是为什么对您的数据库/组织中的套管约定很重要的原因,然后坚持下去( haster/a>很常见)

一种替代方案,尽管也很容易易碎,但根本不是与命名参数结合,而是使用参数的序数位置来绑定它,例如.

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)

其他推荐答案

我刚刚遇到了同样的问题,这里是我的发现:::

此错误的原因是,在创建函数后,PostgreSQL会自动将函数名称和参数名称转换为小写.当NPGSQL调用此函数时,函数名称不敏感,但参数名称是案例敏感的.

我已经花了一半时间寻找错误来源.只需将NPGSQL从2.2.5升级到4.1.5,PostgreSQL从9到13,我的代码停止与42883: function does not exist

一起工作

我已经使所有参数都在C#代码

中为小写
var data = dataConnection.QueryProc<FormOutput>("get_form_data", new[] {
    new DataParameter("countryid", countryId),
    new DataParameter("keyvalue", key),
    new DataParameter("maxqty", maxFormQty) });

处理此错误

功能声明低于

create or replace FUNCTION get_form_data (countryId varchar, key varchar, maxQty int)

本文地址:https://www.itbaoku.cn/post/1763951.html

问题描述

scratching my head on this. There's a similar question that might be related at "function does not exist," but I really think it does and PostgreSQL function does not exist but the answer(s) does not seem very obvious. PostgreSQL 9.5.

I have an Npgsql-based membership query that looks like this:

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();
        }
    }
}

This function exists in my postgresql db as:

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);

I've checked, double-checked, and triple-checked the connection string... it's pointed to this db, with the proper login. The function executes fine from a pgAdmin window.

my connection string resembles this:

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

...with these credentials, I can see the function:enter image description here

Yet, when I am using this as a referenced library in my asp.net project, I get the following message:

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]

I've used this library for a while, but this is the first time I've seen this message. Is there something I'm missing?

推荐答案

So @JGH caught the fact that the signature variable names in the error message are slightly different in the library than in the posted code... which shouldn't have happened, but I pulled down the source code, compiled it as a dependency project, and everything worked fine. So, the pre-compiled library has a problem, and I can work around it.

Thanks for the help!

其他推荐答案

Note that postgres allows function overloading, so not only does the function NAME need to exist, but the types of the function parameters will also be used to determine which overload to use, e.g.

CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, varchar, boolean)   

Is not the same function as

CREATE OR REPLACE FUNCTION public.get_user_by_username(varchar, boolean, varchar)

etc.

When calling these functions, the parameter names, types and possibly orders must all match, else you'll get the

Npgsql.PostgresException: 42883: function does not exist

One additional gotcha which keeps biting me is Postgressql's case-sensitivity rules when defining functions. For example, without any surrounding "" quotes, the following function definition (using the default settings in pgAdmin 3):

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

registers the function with the signature: (use an IDE tool to verify this)

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

As a result, any attempt in C# to bind to

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

will fail with the error. Instead, you will need to bind against the all-lower-case parameters, i.e.

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

Unless you define the Function with Quotes:

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

That's why it's important for you to agree on a casing convention in your database / organisation, and then stick to it (all lowercase is quite common)

An alternative, albeit also prone to being fragile, is not to bind with named parameters at all, and instead use the ordinal position of the parameter, to bind it e.g.

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)

其他推荐答案

I've just got the same problem and here is my finding:

The reason for this error is that after the function is created, PostgreSQL automatically converts the function name and parameter name to lowercase. When Npgsql calls this function, the function name is not case sensitive, but the parameter name is case sensitive.

I've spend half of the day looking for the error origin. Just have upgrated Npgsql from 2.2.5 to 4.1.5, PostgreSQL from 9 to 13 and my code stopped to work with 42883: function does not exist

I've made all parameters to be lowercase in the C# code

var data = dataConnection.QueryProc<FormOutput>("get_form_data", new[] {
    new DataParameter("countryid", countryId),
    new DataParameter("keyvalue", key),
    new DataParameter("maxqty", maxFormQty) });

to deal with this error

Function declaration is below

create or replace FUNCTION get_form_data (countryId varchar, key varchar, maxQty int)