Npgsql / Postgresql:"功能不存在"它的错误信息

时间:2017-06-29 00:49:49

标签: c# sql postgresql npgsql

抓住这个问题。还有一个类似的问题可能与"function does not exist," but I really think it doesPostgreSQL 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;

...使用这些凭据,我可以看到函数:enter image description here

然而,当我在我的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]

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

3 个答案:

答案 0 :(得分:2)

一个额外的问题,一直咬着我

  

Npgsql.PostgresException:42883:函数不存在

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

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

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

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)

答案 1 :(得分:1)

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

感谢您的帮助!

答案 2 :(得分:0)

我遇到了同样的问题,这里是my finding

此错误的原因是函数创建后,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)
相关问题