Tengo que ejecutar un bucle en la base de datos. Este es solo un requisito de una vez. Después de ejecutar la función, la descarto ahora.
¿Existe algún buen enfoque para crear funciones temporales / desechables?
fuente
Tengo que ejecutar un bucle en la base de datos. Este es solo un requisito de una vez. Después de ejecutar la función, la descarto ahora.
¿Existe algún buen enfoque para crear funciones temporales / desechables?
Necesitaba saber cómo usar el tiempo en un guión que estaba escribiendo. Resulta que puedes crear una función temporal usando el esquema pg_temp. Este es un esquema que se crea a pedido para su conexión y es donde se almacenan las tablas temporales. Cuando su conexión se cierra o caduca, este esquema se elimina. Resulta que si crea una función en este esquema, el esquema se creará automáticamente. Por lo tanto,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
será una función que se mantendrá siempre que su conexión se mantenga. No es necesario llamar a un comando de caída.
Un par de notas adicionales al truco inteligente en la respuesta de @ crowmagnumb :
pg_temp
está en el search_path
(como está por defecto), según Tom Lane para evitar los caballos de Troya:CREATE FUNCTION pg_temp.f_inc(int)
RETURNS int AS 'SELECT $1 + 1' LANGUAGE sql IMMUTABLE;
SELECT pg_temp.f_inc(42);
f_inc
-----
43
Una función creada en el esquema temporal solo es visible dentro de la misma sesión (al igual que las tablas temporales). Es invisible para todas las demás sesiones (incluso para el mismo rol). Usted podría tener acceso a la función como un papel diferente en la misma sesión después SET ROLE
.
Incluso podría crear un índice funcional basado en esta función "temporal":
CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
De este modo, se crea un índice simple utilizando una función temporal en una tabla no temporal. Dicho índice sería visible para todas las sesiones, pero solo sería válido para la sesión de creación. El planificador de consultas no utilizará un índice funcional, donde la expresión no se repite en la consulta. Todavía es un truco sucio. Se eliminará automáticamente cuando se cierre la sesión, como un objeto dependiente. Siente que esto no debería permitirse en absoluto ...
Si solo necesita ejecutar una función repetidamente y todo lo que necesita es SQL, considere una declaración preparada en su lugar. Actúa de forma muy similar a una función SQL temporal que muere al final de la sesión. Sin embargo, no es lo mismo y solo se puede usar por sí mismo EXECUTE
, no anidado dentro de otra consulta. Ejemplo:
PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;
Llamada:
EXECUTE upd_tbl(123, 'foo_name');
Detalles:
Si está utilizando la versión 9.0, puede hacer esto con la nueva declaración DO:
http://www.postgresql.org/docs/current/static/sql-do.html
Con versiones anteriores, deberá crear la función, llamarla y soltarla nuevamente.
pg_temp.foo()
. No entiendo por qué (!?) Hoy, 2014, con ejemplos tan simples y rápidos como Lua , los lenguajes SQL DML no pueden ofrecer funciones lambda (!).DO
declaraciones no pueden tener parámetros de entrada y no pueden devolver un resultado, al contrario de las funciones.Para los procedimientos ad hock, los cursores no son tan malos. Sin embargo, son demasiado ineficientes para su uso productino.
Le permitirán recorrer fácilmente los resultados de SQL en la base de datos.
fuente