Вот функция pl / pgsql, которая находит записи, где любой столбец содержит определенное значение.
Он принимает в качестве аргументов значение для поиска в текстовом формате, массив имен таблиц для поиска (по умолчанию для всех таблиц) и массив имен схем (по умолчанию для всех имен схем).
Возвращает структуру таблицы со схемой, именем таблицы, именем столбца и псевдостолбца ctid
(недолговременное физическое расположение строки в таблице, см. Системные столбцы )
CREATE OR REPLACE FUNCTION search_columns(
needle text,
haystack_tables name[] default '{}',
haystack_schema name[] default '{}'
)
RETURNS table(schemaname text, tablename text, columnname text, rowctid text)
AS $$
begin
FOR schemaname,tablename,columnname IN
SELECT c.table_schema,c.table_name,c.column_name
FROM information_schema.columns c
JOIN information_schema.tables t ON
(t.table_name=c.table_name AND t.table_schema=c.table_schema)
WHERE (c.table_name=ANY(haystack_tables) OR haystack_tables='{}')
AND (c.table_schema=ANY(haystack_schema) OR haystack_schema='{}')
AND t.table_type='BASE TABLE'
LOOP
EXECUTE format('SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L',
schemaname,
tablename,
columnname,
needle
) INTO rowctid;
IF rowctid is not null THEN
RETURN NEXT;
END IF;
END LOOP;
END;
$$ language plpgsql;
РЕДАКТИРОВАТЬ : этот код для PG 9.1 или новее. Также вам может потребоваться версия на github , основанная на том же принципе, но с некоторыми улучшениями в скорости и отчетности.
Примеры использования в тестовой базе данных:
Поиск во всех таблицах в публичной схеме:
select * from search_columns('foobar');
schemaname | tablename | columnname | rowctid
------------+-----------+------------+---------
public | s3 | usename | (0,11)
public | s2 | relname | (7,29)
public | w | body | (0,2)
(3 rows)
Поиск в конкретной таблице:
select * from search_columns('foobar','{w}');
schemaname | tablename | columnname | rowctid
------------+-----------+------------+---------
public | w | body | (0,2)
(1 row)
Поиск в подмножестве таблиц, полученных из выбора:
select * from search_columns('foobar', array(select table_name::name from information_schema.tables where table_name like 's%'), array['public']);
schemaname | tablename | columnname | rowctid
------------+-----------+------------+---------
public | s2 | relname | (7,29)
public | s3 | usename | (0,11)
(2 rows)
Получить строку результатов с соответствующей базовой таблицей и и ctid:
select * from public.w where ctid='(0,2)';
title | body | tsv
-------+--------+---------------------
toto | foobar | 'foobar':2 'toto':1
Чтобы снова проверить регулярное выражение вместо строгого равенства, например, grep, это:
SELECT ctid FROM %I.%I WHERE cast(%I as text)=%L
может быть изменено на:
SELECT ctid FROM %I.%I WHERE cast(%I as text) ~ %L