Npgsql/ Postgresql: “function does not exist” error message when it does

老子叫甜甜 提交于 2019-12-05 12:32:10

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)

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!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!