Postgres - Как мне вызвать сохраненную функцию plpgsql, я сделал ошибку в самой функции?

Я написал функцию Postgres, используя plpgsql, но получаю «синтаксическую ошибку, неожиданный символ», когда я вызываю ее, используя:

PERFORM create_user('a', 'b', 'c');

Вот определение функции Postgres, скопированное из pgAdmin:

CREATE OR REPLACE FUNCTION create_user(_username character varying, _passwordhash character varying, _email character varying)
RETURNS integer AS
$BODY$
BEGIN

INSERT INTO users(id, username, passwordhash, email) VALUES (DEFAULT, _username, _passwordhash, _email) RETURNING id;


END;$BODY$
LANGUAGE plpgsql VOLATILE SECURITY DEFINER
COST 100;
ALTER FUNCTION create_user(character varying, character varying, character varying)
OWNER TO postgres;

Может ли кто-нибудь определить, что я сделал неправильно здесь?

Кроме того, я пытаюсь получить к нему доступ в node.js через «pg», но мне все равно не удалось вызвать функцию без синтаксической ошибки из pgAdmin.


person user1315172    schedule 25.07.2014    source источник


Ответы (2)


Почему бы вам не попробовать свою функцию, как показано ниже; объявив переменную INT, а затем запишите сгенерированную последовательность id в переменную. Наконец, верните эту переменную.

В одном сообщении на форуме Postgres я обнаружил, что конструкция RETURNING id поддерживается не во всех версиях. поэтому вы можете обойти это другим способом.

CREATE OR REPLACE FUNCTION create_user(_username character varying,
                                       _passwordhash character varying, 
                                       _email character varying)
RETURNS integer AS
$BODY$
DECLARE retvar integer; <-- declare the variable
BEGIN

  INSERT INTO users(id, username, passwordhash, email) 
  VALUES (DEFAULT, _username, _passwordhash, _email) RETURNING id into retvar;
                                                             <-- get return id
return retvar; <-- return the variable
END;
$BODY$
person Rahul    schedule 25.07.2014
comment
Мне удалось заставить его работать, используя следующее: CREATE OR REPLACE FUNCTION create_user(username character varying, password_hash character varying, email character varying) RETURNS integer AS $BODY$INSERT INTO users (username, passwordhash, email) VALUES ($1, $2, $2) RETURNING id$BODY$ LANGUAGE sql VOLATILE COST 100; ALTER FUNCTION create_user(character varying, character varying, character varying) OWNER TO postgres; Я думаю, как и в вашем примере, он использует язык SQL, а не plpgsql. - person user1315172; 26.07.2014
comment
Насколько я могу судить, на самом деле это не хранимая функция plpgsql. - person user1315172; 26.07.2014
comment
@ user1315172, приятно знать, что у тебя все получилось. с вашим комментарием вы имеете в виду, что мой ответ вам не помог? - person Rahul; 26.07.2014
comment
Ваш комментарий был полезен, но я не запускал его, чтобы убедиться, что это правильный ответ на вопрос и работает ли он. Я решил проблему не с помощью метода, который я сформулировал для этого вопроса, поскольку он использовал обычный SQL, а не plpgsql. Мне также интересно узнать, написан ли ваш пример на plpgsql или на стандартном (ANSI?) SQL. Судя по всему, он использует plpgsql, потому что параметры не записываются как $1, $2 и т. д. Может ли запись «LANGUAGE plpgsql» в вашем примере вообще изменить то, что он делает? - person user1315172; 26.07.2014
comment
Вы имеете в виду, что ваш пример написан на plpgsql? - person user1315172; 26.07.2014
comment
Да, так как ваш опубликованный код написан на plpgsql. Более того, я ничего особенного не добавил. просто пошел по вашему опубликованному коду и немного изменил тело. - person Rahul; 26.07.2014
comment
Потому что я не решил это по-другому (с обычным SQL), когда задавал вопрос. В любом случае, спасибо за исправление моего кода. Как только я подтвержу, что это работает, я подтвержу вопрос как ответ. - person user1315172; 26.07.2014
comment
Потребовался дополнительный оператор LANGUAGE plpgsql после $BODY$, но это сработало. - person user1315172; 28.07.2014

Предположительно, вы вводите это в редакторе SQL pgAdmin:

PERFORM create_user('a', 'b', 'c');

Это завершается ошибкой синтаксиса, потому что PERFORM не является обычной инструкцией SQL. Глядя на справочный список команд SQL в документации, вы увидим, что это не их часть.

PERFORM относится только к языку pl/pgsql и поэтому может использоваться только внутри функции pl/pgsql. Это задокументировано как:

Иногда бывает полезно оценить выражение или запрос SELECT, но отбросить результат, например, при вызове функции, которая имеет побочные эффекты, но не имеет полезного значения результата. Чтобы сделать это в PL/pgSQL, используйте оператор PERFORM:

ВЫПОЛНИТЬ запрос;

Это выполняет запрос и отбрасывает результат

Чтобы вызвать функцию из pgAdmin или из другого клиентского приложения, просто используйте SELECT, независимо от языка функции и независимо от того, какой тип она возвращает.

person Daniel Vérité    schedule 27.07.2014