J'ai cette fonction dans PostgreSQL, mais je ne sais pas comment renvoyer le résultat de la requête:
CREATE OR REPLACE FUNCTION wordFrequency(maxTokens INTEGER)
RETURNS SETOF RECORD AS
$$
BEGIN
SELECT text, count(*), 100 / maxTokens * count(*)
FROM (
SELECT text
FROM token
WHERE chartype = 'ALPHABETIC'
LIMIT maxTokens
) as tokens
GROUP BY text
ORDER BY count DESC
END
$$
LANGUAGE plpgsql;
Mais je ne sais pas comment renvoyer le résultat de la requête dans la fonction PostgreSQL.
J'ai trouvé que le type de retour devrait être SETOF RECORD
, non? Mais la commande de retour n'est pas correcte.
Quel est le bon moyen de le faire?
sql
postgresql
return
plpgsql
return-type
Renato Dinhani
la source
la source
LANGUAGE SQL
.Réponses:
Utilisez
RETURN QUERY
:Appel:
Explication:
Il est beaucoup plus pratique de définir explicitement le type de retour que de simplement le déclarer comme enregistrement. De cette façon, vous n'avez pas à fournir une liste de définitions de colonne à chaque appel de fonction.
RETURNS TABLE
est une façon de faire cela. Il y en a d'autres. Les types de données desOUT
paramètres doivent correspondre exactement à ce qui est renvoyé par la requête.Choisissez
OUT
soigneusement les noms des paramètres. Ils sont visibles dans le corps de fonction presque partout. Qualifiez les colonnes du même nom pour éviter les conflits ou les résultats inattendus. Je l'ai fait pour toutes les colonnes de mon exemple.Mais notez le conflit de dénomination potentiel entre le
OUT
paramètrecnt
et l'alias de colonne du même nom. Dans ce cas particulier (RETURN QUERY SELECT ...
) Postgres utilise l'alias de colonne sur leOUT
paramètre de toute façon. Cela peut cependant être ambigu dans d'autres contextes. Il existe plusieurs moyens d'éviter toute confusion:ORDER BY 2 DESC
. Exemple:ORDER BY count(*)
.plpgsql.variable_conflict
ou utilisez la commande spéciale#variable_conflict error | use_variable | use_column
dans la fonction. Voir:N'utilisez pas «texte» ou «compte» comme noms de colonne. Les deux sont légaux à utiliser dans PostgreSQL, mais "count" est un mot réservé dans SQL standard et un nom de fonction de base et "texte" est un type de données de base. Peut conduire à des erreurs déroutantes. J'utilise
txt
etcnt
dans mes exemples.Ajout d'une
;
erreur de syntaxe manquante et corrigée dans l'en-tête.(_max_tokens int)
, pas(int maxTokens)
- tapez après le nom .Lorsque vous travaillez avec une division entière, il est préférable de multiplier d'abord et de diviser plus tard, pour minimiser l'erreur d'arrondi. Mieux encore: travaillez avec
numeric
(ou un type à virgule flottante). Voir ci-dessous.Alternative
Voici à quoi je pense que votre requête devrait ressembler (calcul d'une part relative par jeton ):
L'expression
sum(t.cnt) OVER ()
est une fonction de fenêtre . Vous pouvez utiliser un CTE au lieu de la sous-requête - jolie, mais une sous-requête est généralement moins chère dans des cas simples comme celui-ci.Une déclaration explicite
RETURN
finale n'est pas requise (mais autorisée) lorsque vous travaillez avec desOUT
paramètres ouRETURNS TABLE
(qui utilise implicitement desOUT
paramètres).round()
avec deux paramètres ne fonctionne que pour lesnumeric
types.count()
dans la sous-requête produit unbigint
résultat et unsum()
over thisbigint
produit unnumeric
résultat, ainsi nous traitonsnumeric
automatiquement un nombre et tout se met en place.la source
RETURN;
avant celaEND;
, du moins je l'ai fait - mais je fais une UNION donc je ne suis pas sûr si cela rend les choses différentes.RETURN
. Correction d'une erreur sans rapport et ajout de quelques améliorations tout en y étant.Salut s'il vous plaît vérifier le lien ci-dessous
https://www.postgresql.org/docs/current/xfunc-sql.html
EX:
la source