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

Я проверил, дважды проверил и трижды проверил строку подключения... она указала на эту базу данных с соответствующим логином. Функция выполняется нормально из окна 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]

Я использовал эту библиотеку некоторое время, но впервые вижу это сообщение. Я что-то упускаю?

2 ответа

Решение

Таким образом, @JGH поймал тот факт, что имена переменных подписи в сообщении об ошибке немного отличаются в библиотеке, чем в опубликованном коде... чего не должно было случиться, но я собрал исходный код, скомпилировал его как проект зависимостей и все работало нормально. Итак, у предварительно скомпилированной библиотеки есть проблема, и я могу обойти ее.

Спасибо за помощь!

Еще одна ошибка, которая продолжает меня кусать

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)

У меня такая же проблема, и вот мой вывод:

Причина этой ошибки в том, что после создания функции 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)
Другие вопросы по тегам