Tengo esta función en PostgreSQL, pero no sé cómo devolver el resultado de la consulta:
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;
Pero no sé cómo devolver el resultado de la consulta dentro de la función PostgreSQL.
Descubrí que el tipo de devolución debería ser SETOF RECORD
, ¿verdad? Pero el comando de retorno no es correcto.
¿Cuál es la forma correcta de hacer esto?
sql
postgresql
return
plpgsql
return-type
Renato Dinhani
fuente
fuente
LANGUAGE SQL
.Respuestas:
Utilizar
RETURN QUERY
:Llamada:
Explicación:
Es mucho más práctico definir explícitamente el tipo de retorno que simplemente declararlo como registro. De esta manera, no es necesario que proporcione una lista de definiciones de columna con cada llamada a función.
RETURNS TABLE
es una forma de hacerlo. Hay otros. Los tipos de datos de losOUT
parámetros deben coincidir exactamente con lo que devuelve la consulta.Elija los nombres de los
OUT
parámetros con cuidado. Son visibles en el cuerpo funcional casi en cualquier lugar. Columnas de calificación de tabla del mismo nombre para evitar conflictos o resultados inesperados. Hice eso para todas las columnas de mi ejemplo.Pero tenga en cuenta el posible conflicto de nombres entre el
OUT
parámetrocnt
y el alias de la columna del mismo nombre. En este caso particular (RETURN QUERY SELECT ...
) Postgres usa el alias de la columna sobre elOUT
parámetro de cualquier manera. Sin embargo, esto puede ser ambiguo en otros contextos. Hay varias formas de evitar confusiones:ORDER BY 2 DESC
. Ejemplo:ORDER BY count(*)
.plpgsql.variable_conflict
o utilice el comando especial#variable_conflict error | use_variable | use_column
en la función. Ver:No utilice "texto" o "contar" como nombres de columna. Ambos son legales para usar en Postgres, pero "contar" es una palabra reservada en SQL estándar y un nombre de función básica y "texto" es un tipo de datos básico. Puede dar lugar a errores confusos. Yo uso
txt
ycnt
en mis ejemplos.Se agregó un
;
error de sintaxis faltante y se corrigió en el encabezado.(_max_tokens int)
, no(int maxTokens)
: escriba después del nombre .Mientras trabaja con la división de enteros, es mejor multiplicar primero y dividir después, para minimizar el error de redondeo. Aún mejor: trabaje con
numeric
(o un tipo de punto flotante). Vea abajo.Alternativa
Esto es lo que yo creo que la consulta en realidad debe ser similar (el cálculo de una participación relativa por ficha ):
La expresión
sum(t.cnt) OVER ()
es una función de ventana . Usted podría utilizar un CTE en lugar de la subconsulta - bonito, pero una sub consulta suele ser más barato en casos sencillos como éste.No se requiere una
RETURN
declaración explícita final (pero se permite) cuando se trabaja conOUT
parámetros oRETURNS TABLE
(que hace un uso implícito deOUT
parámetros).round()
con dos parámetros solo funciona paranumeric
tipos.count()
en la subconsulta produce unbigint
resultado y unsum()
over thisbigint
produce unnumeric
resultado, por lo que tratamos con unnumeric
número automáticamente y todo encaja en su lugar.fuente
RETURN;
antes de esoEND;
, al menos yo lo hice, pero estoy haciendo UNION, así que no estoy seguro de si eso lo hace diferente.RETURN
. Se corrigió un error no relacionado y se agregaron algunas mejoras mientras lo hacía.Hola, por favor revisa el siguiente enlace
https://www.postgresql.org/docs/current/xfunc-sql.html
EX:
fuente