Muszę wykonać pętlę w bazie danych. Jest to wymóg jednorazowy. Po wykonaniu funkcji porzucam teraz funkcję.
Czy istnieje dobre podejście do tworzenia funkcji tymczasowych / jednorazowych?
Odpowiedzi:
Musiałem wiedzieć, jak wykonać wielokrotne użycie w scenariuszu, który pisałem. Okazuje się, że możesz utworzyć tymczasową funkcję za pomocą schematu pg_temp. To jest schemat, który jest tworzony na żądanie dla twojego połączenia i tam są przechowywane tymczasowe tabele. Po zamknięciu lub wygaśnięciu połączenia ten schemat jest odrzucany. Okazuje się, że jeśli utworzysz funkcję na tym schemacie, schemat zostanie utworzony automatycznie. W związku z tym,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
będzie funkcją, która będzie się utrzymywać tak długo, jak długo utrzymuje się połączenie. Nie ma potrzeby wywoływania polecenia drop.
Kilka dodatkowych uwag do inteligentnej sztuczki w odpowiedzi @ crowmagnumb :
pg_temp
znajduje się w search_path
(tak jak jest to domyślnie), według Tom Lane, aby zapobiec koniom trojańskim: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
Funkcja utworzona w schemacie tymczasowym jest widoczna tylko w tej samej sesji (podobnie jak tabele tymczasowe). Jest niewidoczny dla wszystkich innych sesji (nawet dla tej samej roli). Państwo mogli uzyskać dostęp do funkcji w innej roli w tej samej sesji po SET ROLE
.
Możesz nawet utworzyć indeks funkcjonalny oparty na tej funkcji „temp”:
CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
W ten sposób tworząc zwykły indeks przy użyciu funkcji tymczasowej w tabeli innej niż tymczasowa. Taki indeks byłby widoczny dla wszystkich sesji, ale nadal ważny tylko dla sesji tworzącej. Planer zapytań nie będzie używał indeksu funkcjonalnego, jeśli wyrażenie nie jest powtarzane w zapytaniu. Wciąż trochę brudna sztuczka. Zostanie automatycznie usunięty po zamknięciu sesji - jako obiekt zależny. Wydaje się, że nie powinno to być w ogóle dozwolone ...
Jeśli potrzebujesz tylko wielokrotnie wykonywać funkcję i potrzebujesz tylko SQL, zamiast tego rozważ przygotowaną instrukcję . Działa podobnie do tymczasowej funkcji SQL, która umiera pod koniec sesji. Jednak to nie to samo i może być używane tylko samodzielnie z EXECUTE
, a nie zagnieżdżone w innym zapytaniu. Przykład:
PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;
Połączenie:
EXECUTE upd_tbl(123, 'foo_name');
Detale:
Jeśli używasz wersji 9.0, możesz to zrobić za pomocą nowej instrukcji DO:
http://www.postgresql.org/docs/current/static/sql-do.html
W przypadku poprzednich wersji musisz utworzyć funkcję, wywołać ją i ponownie upuścić.
pg_temp.foo()
. Nie rozumiem, dlaczego (!?) Dzisiaj, 2014, przy tak prostych i szybkich przykładach jak Lua , języki SQL DML nie oferują funkcji lambda (!).
DO
instrukcje nie mogą mieć parametrów wejściowych i nie mogą zwracać wyniku, w przeciwieństwie do funkcji.
W przypadku procedur ad hock kursory nie są takie złe. Są jednak zbyt nieefektywne do użytku w produktach.
Pozwolą ci łatwo zapętlić wyniki sql w db.