#postgresql #function
Вопрос:
Пытаясь создать свою первую функцию PostgreSQL, я не понимаю, почему я не могу вызвать эту функцию.
CREATE FUNCTION public."SampledImpCountToOriginal"(IN integer)
RETURNS numeric
LANGUAGE 'plpgsql'
AS $BODY$
BEGIN
RETURN CASE WHEN $1 > 4 THEN EXP(POW($1 - 1.88, 1/2.3)) ELSE $1 END;
END;
$BODY$;
SELECT SampledImpCountToOriginal(5)
ОШИБКА: функция sampledimpcounttooriginal(целое число) не существует
СТРОКА 1: ВЫБЕРИТЕ SampledImpCountToOriginal(5)
^ ПОДСКАЗКА: Ни одна функция не соответствует заданному имени и типам аргументов. Возможно, вам потребуется добавить явные приведения типов. Состояние SQL:
42883 Символ: 8
Звоню из той же базы данных, в которой я ее создал, пытался сменить владельца, не могу понять. Функция указана в pgAdmin как SampledImpCountToOriginal(IN integer)
.
Ответ №1:
Ты должен позвонить вот так — SELECT "SampledImpCountToOriginal"(5)
Когда бы вы ни использовали Double Quotes ""
create Function
это , вы должны использовать в процессе вызова. Нравится —
SELECT public."SampledImpCountToOriginal"(
<integer>
)
Если вы не привыкли double quotes ""
звонить своим created function with ""
. он выполняет другую функцию.
SELECT public.sampledimpcounttooriginal(
<integer>
)
Комментарии:
1. Спасибо! Спасатель. Я отбросил функцию и переопределил ее без кавычек. Я изначально создал функцию с помощью pgAdmin, и она вставила кавычки… сбивающее с толку поведение.
Почесывая голову от этого. Есть похожий вопрос, который может быть связан с «функция не существует», но я действительно думаю, что она существует, и функция 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]
Я использовал эту библиотеку некоторое время, но впервые вижу это сообщение. Я что-то упускаю?
2017-06-29 00:49
2
ответа
Решение
Таким образом, @JGH поймал тот факт, что имена переменных подписи в сообщении об ошибке немного отличаются в библиотеке, чем в опубликованном коде… чего не должно было случиться, но я собрал исходный код, скомпилировал его как проект зависимостей и все работало нормально. Итак, у предварительно скомпилированной библиотеки есть проблема, и я могу обойти ее.
Спасибо за помощь!
2017-06-30 01:10
Еще одна ошибка, которая продолжает меня кусать
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)
2017-07-13 12:00
У меня такая же проблема, и вот мой вывод:
Причина этой ошибки в том, что после создания функции 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)
2020-11-06 11:45
Я сейчас работаю над проектом, где я пытаюсь создать триггер, который обновляет столбец «lastedit» (в таблице Person), который является отметкой времени, когда последнее изменение было внесено в таблицу в указанной схеме в создании триггера (в этом случае Сертификаты).
Теперь моя проблема в том, что когда я пытаюсь создать триггер, после создания функции «update_lastedit()», это дает мне ошибку, говоря, что функция не существует. Я думаю, что у меня может быть несоответствие в моей функции где-то, но я не могу найти ее.
Может ли кто-нибудь из вас помочь мне? Я запускаю PostgreSQL 9.5.5. Пожалуйста, дайте мне знать, если мне нужно дать более подробное объяснение, это мой первый вопрос, поэтому я мог упустить что-то важное.
Мой код для триггера и функции:
CREATE OR REPLACE FUNCTION update_lastedit() RETURNS TRIGGER AS
$update_edit$
BEGIN
UPDATE ovsoftware.person
SET lastedit = now();
END;
$update_edit$
LANGUAGE plpgsql;
а также
CREATE TRIGGER cert_edit_trigger
BEFORE INSERT OR UPDATE ON ovsoftware.certifications
FOR EACH ROW
EXECUTE PROCEDURE update_lastedit();
Точная ошибка:
SQL fout:
ERROR: function update_lastedit() does not exist
In statement:
CREATE TRIGGER cert_edit_trigger
BEFORE INSERT OR UPDATE ON ovsoftware.certifications
FOR EACH ROW
EXECUTE PROCEDURE update_lastedit();