web-dev-qa-db-fra.com

Comment appeler une fonction, PostgreSQL

J'essaie d'utiliser une fonction avec PostgreSQL pour sauvegarder des données. Voici le script de création:

-- Function: "saveUser"(integer, character varying, character varying, character varying, character varying, character varying)

-- DROP FUNCTION "saveUser"(integer, character varying, character varying, character varying, character varying, character varying);

CREATE OR REPLACE FUNCTION "saveUser"("pUserID" integer, "pName" character varying, "pLastName" character varying, "pUserName" character varying, "pPassword" character varying, "peMail" character varying)
  RETURNS boolean AS
$BODY$
BEGIN
SELECT 1
FROM "USERS"
WHERE "userID" = $1;

IF FOUND THEN
UPDATE "USERS" 
    SET     "name" = $2,
    "lastName" = $3,
    "userName" = $4,
    "password" = $5,
    "eMail" = $6
WHERE "userID" = $1;
ELSE
    INSERT INTO "USERS"
    ("name", "lastName", "userName", "password", "eMail")
    VALUES
        ($2, $3, $4, $5, $6);
END IF;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION "saveUser"(integer, character varying, character varying, character varying, character varying, character varying) OWNER TO postgres;

La documentation PostreSQL indique que pour appeler une fonction qui ne renvoie aucun résultat, il suffit d'écrire son nom et ses propriétés. Alors j'essaie d'appeler la fonction comme ceci:

"saveUser"(3, 'asd','asd','asd','asd','asd');

Mais je reçois l'erreur ci-dessous:

ERROR:  syntax error at or near ""saveUser""
LINE 1: "saveUser"(3, 'asd','asd','asd','asd','asd')
     ^

********** Error **********

ERROR: syntax error at or near ""saveUser""
SQL state: 42601
Character: 1

J'ai d'autres fonctions qui renvoient un résultat. J'utilise SELECT * FROM "fnc"(...) pour les appeler et cela fonctionne. Pourquoi est-ce que je reçois cette erreur? 


EDIT: J'utilise l'outil de requête pgAdmin III et j'essaie d'y exécuter les instructions SQL.

31
Erkan Haspulat

L'appel de fonction doit toujours être une instruction SQL valide:

SELECT "saveUser"(3, 'asd','asd','asd','asd','asd');
47
Milen A. Radev

Pour Postgresql, vous pouvez utiliser PERFORM . PERFORM n'est valide que dans le langage de procédure PL/PgSQL.

DO $$ BEGIN
    PERFORM "saveUser"(3, 'asd','asd','asd','asd','asd');
END $$;

La suggestion de l'équipe postgres:

CONSEIL: si vous souhaitez ignorer les résultats d'un SELECT, utilisez plutôt PERFORM.

10
itsnikolay

si votre fonction ne veut rien renvoyer, vous devez la déclarer comme "renvoyer une annulation" et vous pourrez l'appeler ainsi: "perform functionName (paramètre ...);"

4
pengli

J'ai eu ce même problème en essayant de tester une fonction très similaire qui utilise une instruction SELECT pour décider si un INSERT ou un UPDATE doit être effectué. Cette fonction était une réécriture d'une procédure stockée T-SQL.
Lorsque j'ai testé la fonction à partir de la fenêtre de requête, l'erreur "La requête n'a pas de destination pour les données de résultat". J'ai finalement compris que, parce que j'avais utilisé une instruction SELECT dans la fonction, je ne pouvais pas la tester depuis la fenêtre de requête avant d'avoir affecté les résultats de SELECT à une variable locale à l'aide d'une instruction INTO. Cela a résolu le problème.

Si la fonction d'origine de ce fil était modifiée comme suit, cela fonctionnerait s'il était appelé à partir de la fenêtre de requête,

$BODY$
DECLARE
   v_temp integer;
BEGIN
SELECT 1 INTO v_temp
FROM "USERS"
WHERE "userID" = $1;
1
G.Bouch