Временные таблицы — это существенно мощный инструмент для разработчика.
Особенно в том случае, если формируется адаптивная (максимально гибкая) информационная система.
Важно!
1. При копировании текстов функций этого раздела, следует «крупно иметь в виду», что существенная часть функций вызывает другие функции (размещенные в этом разделе, а также и в других разделах тоже).
2. Чтобы компенсировать этот момент — в конце страницы можно скачать исходные тексты всех функций в формате PG-backup (SQL-текст).
- table_tmp_tn_is_ok — проверить, что заданное имя таблицы БД может соответствовать имени ВРЕМЕННОЙ таблицы;
- table_tmp_drop — удалить таблицу tn (если она временная);
- table_tmp_clear — очистить (удалить строки) таблицу tn (если она временная);
- table_tmp_delete — удалить строки из заданной временной таблицы, согласно заданного фильтра;
- table_tmp_create — создать временную таблицу (предварительно — предыдущая, с таким же именем, автоматически удаляется);
- table_tmp_create_as — создать временную таблицу БД на основе существующей таблицы БД (предварительно — предыдущая, с таким же именем, автоматически удаляется);
См., также, в HTML-формате
CREATE OR REPLACE FUNCTION public.table_tmp_tn_is_ok(tn character varying) RETURNS boolean AS $BODY$ DECLARE res boolean; k integer; BEGIN -- Проверить, что tn может соответствовать имени ВРЕМЕННОЙ таблицы -- select * from table_tmp_tn_is_ok('a333'); -- select * from table_tmp_tn_is_ok('tmp999.fff_pars'); -- select * from table_tmp_tn_is_ok('dir.variants_list'); res = false; tn = str_is_null(tn); IF (tn <> '') THEN tn = lower(tn); k = position('.' in tn); IF (k<=0) THEN k = 0; /* -- Здесь исключения (т.е., если в схеме public есть таблицы Б.Д., то их нужно указать здесь) -- IF (tn = 'props_types') THEN k = 1; END IF; */ IF (k<=0) THEN res = true; END IF; END IF; END IF; RETURN res; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; COMMENT ON FUNCTION public.table_tmp_tn_is_ok(character varying) IS 'Проверить, что tn может соответствовать имени ВРЕМЕННОЙ таблицы';
CREATE OR REPLACE FUNCTION public.table_tmp_drop(tn character varying) RETURNS boolean AS $BODY$ DECLARE res boolean; BEGIN -- Удалить таблицу tn (если она временная) -- select * from table_tmp_drop('a333'); res = false; tn = str_is_null(tn); IF (table_tmp_tn_is_ok(tn) = true) THEN tn = lower(tn); res = public.exec_sql_text('drop table if exists ' || tn || ';'); res = bool_is_null(res); END IF; RETURN res; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; COMMENT ON FUNCTION public.table_tmp_drop(character varying) IS 'Удалить таблицу tn (если она временная)';
CREATE OR REPLACE FUNCTION public.table_tmp_create( tn character varying, sqltext text) RETURNS boolean AS $BODY$ DECLARE res boolean; yesnext boolean; k integer; BEGIN -- Создать временную таблицу (предварительно - предыдущая, с таким же именем, автоматически удаляется) -- select * from table_tmp_create('a333', 'CREATE temporary TABLE IF NOT EXISTS a333 (id serial, nav_namemax character varying(100)); CREATE INDEX a333_id ON a333(id);'); -- select * from table_tmp_create('a333', 'CREATE temporary TABLE a333 (id serial, nav_namemax character varying(100)); CREATE INDEX a333_id ON a333(id);'); -- select * from a333; -- select * from public.table_tmp_drop('a333'); res = false; tn = str_is_null(tn); IF (table_tmp_tn_is_ok(tn) = true) THEN -- контроль имени таблицы (что это временная) tn = lower(tn); sqltext = str_is_null(sqltext); IF (sqltext <> '') THEN yesnext = true; -- ------------------------------------------- -- простейший контроль имени таблицы и намерений программиста в sql-запросе k = position('CREATE' in upper(sqltext)); IF (k<=0) THEN yesnext = false; END IF; k = position('TEMPORARY' in upper(sqltext)); IF (k<=0) THEN yesnext = false; END IF; k = position('TABLE' in upper(sqltext)); IF (k<=0) THEN yesnext = false; END IF; k = position(upper(tn) in upper(sqltext)); IF (k<=0) THEN yesnext = false; END IF; -- ------------------------------------------- -- ------------------------------------------- IF (yesnext = true) THEN yesnext = public.table_tmp_drop(tn); -- удаляем предыдущую, если существует res = public.exec_sql_text(sqltext); res = bool_is_null(res); END IF; -- ------------------------------------------- END IF; END IF; RETURN res; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; COMMENT ON FUNCTION public.table_tmp_create(character varying, text) IS 'Создать временную таблицу (предварительно - предыдущая, с таким же именем, автоматически удаляется)';
CREATE OR REPLACE FUNCTION public.table_tmp_create_as( tn_tmp character varying, tn_from character varying, sfilter character varying DEFAULT ''::character varying) RETURNS boolean AS $BODY$ DECLARE res boolean; sqltext text; BEGIN /* Создать временную таблицу БД на основе существующей таблицы БД (предварительно - предыдущая, с таким же именем, автоматически удаляется) Вх. параметры: tn_tmp - имя создаваемой (временной) таблицы БД; tn_from - имя таблицы БД, на основе которой создается tn_tmp; sfilter - фильтр, для копирования строк из таблицы tn_from в таблицу tn_tmp (необязательный параметр); Вых. параметры: =TRUE - успешно; =FALSE - ошибка Пример-1: select * from table_tmp_create_as('a333', 'dir.ot_list'); select * from a333; select * from public.table_tmp_drop('a333'); Пример-2: select * from table_tmp_create('a333', 'CREATE temporary TABLE a333 (id integer, namemax character varying(100));'); --select * from a333; select * from exec_select('id, namemax from a333') as ds(id integer, namemax character varying); select exec_sql_text('insert into a333 (id, namemax) values (1,' || q39_lr('Object-1') || ')'); select exec_sql_text('insert into a333 (id, namemax) values (2,' || q39_lr('Объект-2') || ')'); select exec_sql_text('insert into a333 (id, namemax) values (3,' || q39_lr('Объект-3') || ')'); --select * from a333; select * from exec_select('id, namemax from a333') as ds(id integer, namemax character varying); select * from table_tmp_create_as('a555', 'a333', 'id>1'); --select * from a555; select * from exec_select('id, namemax from a555') as ds(id integer, namemax character varying); select * from table_tmp_drop('a333'); */ res = false; tn_tmp = lower(str_is_null(tn_tmp)); if (table_tmp_tn_is_ok(tn_tmp) = true) THEN -- контроль имени таблицы (что это временная) tn_from = str_is_null(tn_from); IF (table_exist( -1, tn_from)= true) THEN sqltext = 'create temporary table ' || tn_tmp || ' as select * from ' || tn_from; sfilter = str_is_null(sfilter); IF (sfilter <> '') THEN sqltext = sqltext || ' where ' || sfilter; END IF; PERFORM public.table_tmp_drop(tn_tmp); -- удаляем предыдущую, если существует res = public.exec_sql_text(sqltext); res = bool_is_null(res); END IF; END IF; RETURN res; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; COMMENT ON FUNCTION public.table_tmp_create_as(character varying, character varying, character varying) IS 'Создать временную таблицу БД на основе существующей таблицы БД (предварительно - предыдущая, с таким же именем, автоматически удаляется)';
CREATE OR REPLACE FUNCTION public.table_tmp_clear(tn character varying) RETURNS boolean AS $BODY$ DECLARE res boolean; BEGIN -- Очистить (удалить строки) таблицу tn (если она временная) -- select * from table_tmp_clear('a333'); res = false; tn = str_is_null(tn); if (table_tmp_tn_is_ok(tn) = true) THEN tn = lower(tn); res = public.exec_sql_text('delete from ' || tn || ';'); res = bool_is_null(res); END IF; RETURN res; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; COMMENT ON FUNCTION public.table_tmp_clear(character varying) IS 'Очистить таблицу tn (если она временная)';
CREATE OR REPLACE FUNCTION public.table_tmp_delete( tn character varying, sfilter character varying) RETURNS boolean AS $BODY$ DECLARE res boolean; BEGIN -- Удалить из таблицы tn (если она временная) строки, согласно фильтра sfilter /* Пример. select * from table_tmp_create('a333', 'CREATE temporary TABLE a333 (id integer, namemax character varying(100));'); --select * from a333; select * from exec_select('id, namemax from a333') as ds(id integer, namemax character varying); select exec_sql_text('insert into a333 (id, namemax) values (1,' || q39_lr('Object-1') || ')'); select exec_sql_text('insert into a333 (id, namemax) values (2,' || q39_lr('Объект-2') || ')'); select exec_sql_text('insert into a333 (id, namemax) values (3,' || q39_lr('Объект-3') || ')'); --select * from a333; select * from exec_select('id, namemax from a333') as ds(id integer, namemax character varying); select * from table_tmp_delete('a333', 'id=2'); --select * from a333; select * from exec_select('id, namemax from a333') as ds(id integer, namemax character varying); select * from table_tmp_drop('a333'); */ res = false; sfilter = str_is_null(sfilter); IF (sfilter <> '') THEN tn = str_is_null(tn); IF (table_tmp_tn_is_ok(tn) = true) THEN tn = lower(tn); res = public.exec_sql_text('delete from ' || tn || ' where ' || sfilter || ';'); res = bool_is_null(res); END IF; END IF; RETURN res; END; $BODY$ LANGUAGE plpgsql VOLATILE COST 100; COMMENT ON FUNCTION public.table_tmp_delete(character varying, character varying) IS 'Удалить из таблицы tn (если она временная) строки, согласно фильтра sfilter';
Скачать PG-backup (SQL-текст функций)
См., также, в HTML-формате
Дата: 26.01.2022