una - procedimientos almacenados en postgresql pdf
Uso de tipos de devoluciĆ³n personalizados en un bucle FOR en plpgsql (1)
my_test
es un tipo compuesto, un tipo de fila, que contiene un único campo entero. No es un integer
.
Al asignar a un registro o tipo de fila en un bucle FOR
todas las columnas de salida de la consulta forman la fila. Su SELECT
necesita devolver una sola columna integer
paréntesis, que luego se anida en un tipo de fila que coincida con su tipo personalizado my_test
.
También puede asignar una lista de variables escalares en un ciclo FOR
, en cuyo caso las columnas de la consulta se asignan de izquierda a derecha a las variables tal como están , sin formar una fila.
Si la columna en sí es un tipo de fila, tiene un nivel de anidación para muchos. La representación de texto de una fila que contiene un campo entero es ''(1)'' (con paréntesis!), Y eso es lo que ve en el mensaje de error.
Puede solucionarlo extrayendo el campo entero de la fila con notación de atributo :
SELECT (foo_out()).*
O (de manera más eficiente para columnas múltiples) descomponiendo con:
SELECT * FROM foo_out()
Código de ejemplo
CREATE FUNCTION foo_out()
RETURNS SETOF my_test AS
$$
SELECT ''(1)''::my_test
$$
LANGUAGE sql;
CREATE FUNCTION foo1()
RETURNS SETOF my_test AS
$$
DECLARE
x my_test;
BEGIN
FOR x IN
SELECT * FROM foo_out()
LOOP
RETURN NEXT x;
END LOOP;
END
$$
LANGUAGE plpgsql;
No cite el nombre del idioma plpgsql
. Es un identificador.
Recuerde que el bucle raramente es necesario, ya que la mayoría de los problemas se resuelven de forma más eficiente con un enfoque basado en conjuntos (solo SQL).
Respuestas relacionadas por Craig y Pavel:
El siguiente código que uso devuelve un número entero 1
:
CREATE TYPE my_test AS (
foo Integer
);
CREATE FUNCTION foo_out()
RETURNS SETOF Integer AS
$$
BEGIN
RETURN QUERY
SELECT 1 as foo;
END
$$
LANGUAGE plpgsql;
CREATE FUNCTION foo1()
RETURNS SETOF my_test
AS $$
DECLARE
x my_test;
BEGIN
FOR x IN
SELECT foo_out()
LOOP
RETURN NEXT x;
END LOOP;
END;
$$
LANGUAGE ''plpgsql'';
select * from foo1();
Pero ¿por qué regresa el mismo código?
ERROR: invalid input syntax for integer: (1)
si cambio el tipo de devolución a:
CREATE FUNCTION foo_out()
RETURNS SETOF my_test
¿Cuál también debería ser un integer
? Podría ser el caso de que el sistema difiera entre el tipo entero y un tipo personalizado que incluya un entero. ¿Qué debería cambiarse para que el uso de tipos personalizados sea posible aquí?