вот код функции
CREATE OR REPLACE FUNCTION common.gent(in_mode text,exclusion int)
RETURNS integer AS
$BODY$
declare --объЯвлЯем переменные
i_res bigint;
i bigint;
rec1 record;
rec2 record;
rec3 record;
curs1 refcursor;
curs2 refcursor;
sql_array text[];
pk_array text[];
pk_str text;
the_sql text;
a_cprop bigint;
a_cpropb bigint;
hranim text[];
i_res2 bigint;
needed_i_res2 bigint;
begin
for rec1 in
select pgn.nspname::text as col_schema, pgcl.relname::text as col_table, pga.attname::text as col_cprops, pgcon.conkey::bigint[] as col_pk_nums,
ARRAY(
select pga2.attname
from pg_attribute as pga2
where (pga2.attrelid = pgcl.oid)
and (pga2.attnum > 0)
order by pga2.attnum
)::text[] as col_all_columns,
--select *
(
select pgcon2.conkey::text
from pg_constraint as pgcon2
where (pgcon2.contype = 'p')
and (pgcon2.conrelid=pgcl.oid)
)::bigint[] as pk_num
--выборка первичных ключей таблицы с которой работаем
from pg_class as pgcl, pg_namespace as pgn, pg_attribute as pga, pg_constraint as pgcon ,pg_class as pgcl2
where (pgcl.relkind = 'r')
and (pgcl.relnamespace = pgn.oid)
and (pgn.nspname = 'common')
and (pga.attrelid = pgcl.oid)
and (pgcl2.relname=in_mode)
and (pga.attnum=pgcon.conkey[1])
and (pgcon.conrelid = pgcl.oid)
and (pgcon.confrelid = pgcl2.oid)
order by pgcl.relname
/*название таблицы к которой все обращаютсЯ
если номер столбца равен номеру вторичного ключа
находим название таблицы с помощью номера в pgcl и conrelid( показывает к какой таблице относитсЯ)
внешний ключ ссылаетсЯ на какую таблицу*/
loop
sql_array := ARRAY[]::text[];
pk_array := ARRAY[]::text[];
pk_str := '';
for i in 1..coalesce(array_upper(rec1.pk_num, 1), 0) loop
pk_array := array_append(pk_array, rec1.col_all_columns[rec1.pk_num[i]]);
end loop;
-- заносим в массив первичные ключи
pk_str := array_to_string(pk_array, ', ');
-- делаем из массива строку
sql_array := array_append(sql_array, 'select ARRAY[' || pk_str || ']::text[] as col_pk_vals, ' || rec1.col_cprops || '::text as col_cprops_vals');
sql_array := array_append(sql_array, 'from ' || (rec1.col_schema || '.' || rec1.col_table));
sql_array := array_append(sql_array, 'order by ' || pk_str);
--sql_array := array_append(sql_array, 'group by ' || rec1.col_cprops || 'count(*)');
sql_array := array_append(sql_array, ';');
the_sql := array_to_string(sql_array, ' ');
--запрос на выборку, сортируем по первичным ключам
-- делаем из массива строку
open curs1 for execute the_sql;
open curs2 for execute the_sql;
while true loop
fetch curs1 into rec2;
if (rec2 is null) then
exit;
end if;
-- a_cprop := rec2.col_cprops_vals;
-- hranim =rec2.col_pk_vals;
while true loop
fetch curs2 into rec3;
if (rec3 is null) then
exit;
end if;
a_cprop := rec2.col_cprops_vals;
hranim =rec2.col_pk_vals;
a_cpropb := rec3.col_cprops_vals;
--if(a_cprop=a_cprop1) then
if (a_cprop=exclusion) then
-- делаем так чтоб не выводились числа для которых разрешены многочисленные ссылки
continue;
end if;
raise notice '_("%"); //%.%.%[%] . PK_table: % ', a_cprop, rec1.col_schema, rec1.col_table, rec1.col_cprops, rec2.col_pk_vals::text, rec3.col_pk_vals::text;
-- end if;
end loop;
end loop;
close curs1;
close curs2;
end loop;
return 0;
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION common.gent(text,int)
OWNER TO postgres;
пытаюсь сделать так что если в БД больше 1 раза обращается FK к PK выбраной таблицы, но получается так что выводит не все значения, и по каким-то причинам rec2 знает только о значениях 1,11,129,48 что за бред, прошу помощи, не догоняю сам
также если будут другие варианты как сделать предлагайте! |