Мені потрібно виконати цикл у базі даних. Це лише одноразова вимога. Після виконання функції я кидаю функцію зараз.
Чи існує хороший підхід для створення тимчасових / одноразових функцій?
Відповіді:
Мені потрібно було знати, як багато разів використовувати сценарій, який я писав. Виявляється, ви можете створити тимчасову функцію, використовуючи схему pg_temp. Це схема, яка створюється на вимогу для вашого з’єднання і там зберігаються тимчасові таблиці. Коли ваше з’єднання закрите або закінчується, ця схема відпадає. Виявляється, якщо ви створюєте функцію на цій схемі, схема буде створена автоматично. Отже,
create function pg_temp.testfunc() returns text as
$$ select 'hello'::text $$ language sql;
буде функцією, яка буде триматися до тих пір, поки триває зв’язок. Не потрібно викликати команду скидання.
Кілька додаткових приміток до розумного трюку у відповіді @ crowmagnumb :
pg_temp
є search_path
(як це за замовчуванням), згідно з Томом Лейном, щоб запобігти троянським коням: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
Функція, створена у тимчасовій схемі, видно лише всередині того ж сеансу (як і тимчасові таблиці). Це невидимо для всіх інших сеансів (навіть для тієї ж ролі). Ви можете отримати доступ до функції як іншу роль у тому ж сеансі після SET ROLE
.
Ви навіть можете створити функціональний індекс на основі цієї функції "temp":
CREATE INDEX foo_idx ON tbl (pg_temp.f_inc(id));
Тим самим створюється звичайний індекс за допомогою тимчасової функції в нечасовій таблиці. Такий індекс буде видимим для всіх сеансів, але все ще буде дійсним лише для сеансу, що створюється. Планувальник запитів не використовуватиме функціональний індекс, де вираз не повторюється у запиті. Все-таки трохи брудний трюк. Він буде автоматично відкинутий, коли сеанс буде закрито - як залежний об’єкт. Таке відчуття взагалі не можна дозволяти ...
Якщо вам просто потрібно виконати функцію неодноразово, і все, що вам потрібно, це SQL, замість цього розгляньте підготовлену заяву . Він діє як тимчасова функція SQL, яка вмирає в кінці сеансу. Чи не те ж саме, хоча і може бути використаний тільки сам по собі з EXECUTE
не вкладено в інший запит. Приклад:
PREPARE upd_tbl AS
UPDATE tbl t SET set_name = $2 WHERE tbl_id = $1;
Дзвінок:
EXECUTE upd_tbl(123, 'foo_name');
Подробиці:
Якщо ви використовуєте версію 9.0, ви можете зробити це за допомогою нового оператора DO:
http://www.postgresql.org/docs/current/static/sql-do.html
У попередніх версіях вам потрібно буде створити функцію, викликати її та знову скинути.
pg_temp.foo()
. Я не розумію, чому (!?) Сьогодні, 2014 року, з такими простими і такими швидкими прикладами, як Lua , мови SQL DML не можуть пропонувати лямбда-функції (!).
DO
оператори не можуть мати вхідні параметри і не можуть повертати результат, на відміну від функцій.
Для ad hock процедур, курсорів не надто погані. Однак вони занадто неефективні для використання продукту.
Вони дозволять вам легко прокручувати результати sql в базі даних.