Postgresql p> 下面是使用上面创建的search_函数的示例 SELECT * FROM search_columns('86192700' , array(SELECT DISTINCT a.column_name::name FROM information_schema.columns AS a INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name) WHERE a.column_name iLIKE '%cep%' AND b.table_type = 'BASE TABLE' AND b.table_schema = 'public' ) , array(SELECT b.table_name::name FROM information_schema.columns AS a INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name) WHERE a.column_name iLIKE '%cep%' AND b.table_type = 'BASE TABLE' AND b.table_schema = 'public') );
在不存储新过程的情况下,您可以使用代码块并执行以获取事件表。您可以按架构、表或列名筛选结果Postgresql p> 下面是使用上面创建的search_函数的示例 SELECT * FROM search_columns('86192700' , array(SELECT DISTINCT a.column_name::name FROM information_schema.columns AS a INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name) WHERE a.column_name iLIKE '%cep%' AND b.table_type = 'BASE TABLE' AND b.table_schema = 'public' ) , array(SELECT b.table_name::name FROM information_schema.columns AS a INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name) WHERE a.column_name iLIKE '%cep%' AND b.table_type = 'BASE TABLE' AND b.table_schema = 'public') );,postgresql,grep,string-matching,Postgresql,Grep,String Matching,在不存储新过程的情况下,您可以使用代码块并执行以获取事件表。您可以按架构、表或列名筛选结果 DO $$ DECLARE value int := 0; sql text := 'The constructed select statement'; rec1 record; rec2 record; BEGIN DROP TABLE IF EXISTS _x; CREATE TEMPORARY TABLE _x ( schema_name text, ta
DO $$
DECLARE
value int := 0;
sql text := 'The constructed select statement';
rec1 record;
rec2 record;
BEGIN
DROP TABLE IF EXISTS _x;
CREATE TEMPORARY TABLE _x (
schema_name text,
table_name text,
column_name text,
found text
);
FOR rec1 IN
SELECT table_schema, table_name, column_name
FROM information_schema.columns
WHERE table_name <> '_x'
AND UPPER(column_name) LIKE UPPER('%%')
AND table_schema <> 'pg_catalog'
AND table_schema <> 'information_schema'
AND data_type IN ('character varying', 'text', 'character', 'char', 'varchar')
LOOP
sql := concat('SELECT ', rec1."column_name", ' AS "found" FROM ',rec1."table_schema" , '.',rec1."table_name" , ' WHERE UPPER(',rec1."column_name" , ') LIKE UPPER(''','%my_substring_to_find_goes_here%' , ''')');
RAISE NOTICE '%', sql;
BEGIN
FOR rec2 IN EXECUTE sql LOOP
RAISE NOTICE '%', sql;
INSERT INTO _x VALUES (rec1."table_schema", rec1."table_name", rec1."column_name", rec2."found");
END LOOP;
EXCEPTION WHEN OTHERS THEN
END;
END LOOP;
END; $$;
SELECT * FROM _x;
DO$$
声明
值int:=0;
sql文本:='构造的select语句';
rec1记录;
rec2记录;
开始
如果存在,则删除表格x;
创建临时表x(
模式名称文本,
表1\u名称文本,
列名称文本,
找到的文本
);
对于rec1 IN
选择表\模式、表\名称、列\名称
从信息_schema.columns
其中表名为“\u x”
和UPPER(列名称)类似UPPER(“%%”)
和表_模式“pg_目录”
和表_schema“信息_schema”
和数据输入(“字符变化”、“文本”、“字符”、“字符”、“字符”、“变量字符”)
环
sql:=concat('SELECT',rec1.“column_name”,'AS“found”FROM',rec1.“table_schema”,'rec1.“table_name”,'WHERE UPPER(',rec1.“column_name”,')类似于UPPER(','%my_substring_to_find_goes_here%,'');
提出通知“%”,sql;
开始
对于执行sql循环中的rec2
提出通知“%”,sql;
插入到_x值中(rec1.“表_模式”,rec1.“表_名称”,rec1.“列_名称”,rec2.“已找到”);
端环;
当其他人
结束;
端环;
完(元);
从x中选择*;
在每个表的每一列中搜索特定值
这并没有定义如何精确匹配。它也没有确切定义返回什么 假设:
- 查找包含文本表示中给定值的任何列的任何行,而不是等于给定值
- 返回表名(
)和元组ID(regclass
),因为这是最简单的ctid
CREATE OR REPLACE FUNCTION search_whole_db(_like_pattern text)
RETURNS TABLE(_tbl regclass, _ctid tid) AS
$func$
BEGIN
FOR _tbl IN
SELECT c.oid::regclass
FROM pg_class c
JOIN pg_namespace n ON n.oid = relnamespace
WHERE c.relkind = 'r' -- only tables
AND n.nspname !~ '^(pg_|information_schema)' -- exclude system schemas
ORDER BY n.nspname, c.relname
LOOP
RETURN QUERY EXECUTE format(
'SELECT $1, ctid FROM %s t WHERE t::text ~~ %L'
, _tbl, '%' || _like_pattern || '%')
USING _tbl;
END LOOP;
END
$func$ LANGUAGE plpgsql;
电话:
提供搜索模式,但不包含%
为什么有点脏?
如果text
表示中的行的分隔符和装饰符可以是搜索模式的一部分,则可能存在误报:
- 列分隔符:
默认设置,
- 整行用括号括起来:
()
- 有些值用双引号括起来
“
可以添加为转义字符\
regclass
对象标识符类型表示为表名,根据当前的search\u路径
,在需要消除歧义时,对模式进行限定:
select TablesCount(‘StringToSearch’);
--遍历数据库中的所有表
CREATE OR REPLACE FUNCTION **TablesCount**(_searchText TEXT)
RETURNS text AS
$$ -- here start procedural part
DECLARE _tname text;
DECLARE cnt int;
BEGIN
FOR _tname IN SELECT table_name FROM information_schema.tables where table_schema='public' and table_type='BASE TABLE' LOOP
cnt= getMatchingCount(_tname,Columnames(_tname,_searchText));
RAISE NOTICE 'Count% ', CONCAT(' ',cnt,' Table name: ', _tname);
END LOOP;
RETURN _tname;
END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification
--返回满足条件的表的计数。
--例如,如果表的任何字段中存在预期文本,
--然后计数将大于0。我们可以找到通知
--在postgres数据库中结果查看器的消息部分
CREATE OR REPLACE FUNCTION **getMatchingCount**(_tname TEXT, _clause TEXT)
RETURNS int AS
$$
Declare outpt text;
BEGIN
EXECUTE 'Select Count(*) from '||_tname||' where '|| _clause
INTO outpt;
RETURN outpt;
END;
$$ LANGUAGE plpgsql;
--获取每个表的字段。使用表的所有列生成where子句
CREATE OR REPLACE FUNCTION **Columnames**(_tname text,st text)
RETURNS text AS
$$ -- here start procedural part
DECLARE
_name text;
_helper text;
BEGIN
FOR _name IN SELECT column_name FROM information_schema.Columns WHERE table_name =_tname LOOP
_name=CONCAT('CAST(',_name,' as VarChar)',' like ','''%',st,'%''', ' OR ');
_helper= CONCAT(_helper,_name,' ');
END LOOP;
RETURN CONCAT(_helper, ' 1=2');
END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification
有一种方法可以实现这一点,而无需创建函数或使用外部工具。通过使用Postgres的
query\u to\u xml()
函数,可以在另一个查询中动态运行查询,可以在多个表中搜索文本。这基于我的回答:
要在架构中的所有表中搜索字符串foo
,可以使用以下命令:
with found_rows as (
select format('%I.%I', table_schema, table_name) as table_name,
query_to_xml(format('select to_jsonb(t) as table_row
from %I.%I as t
where t::text like ''%%foo%%'' ', table_schema, table_name),
true, false, '') as table_rows
from information_schema.tables
where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
left join xmltable('//table/row'
passing table_rows
columns
table_row text path 'table_row') as x on true
请注意,使用xmltable
需要Postgres 10或更高版本。对于较旧的Postgres版本,也可以使用xpath()完成此操作
公共表表达式(WITH…
)仅用于方便。它在public
架构中的所有表中循环。对于每个表,通过query\u to\u xml()
函数运行以下查询:
select to_jsonb(t)
from some_table t
where t::text like '%foo%';
where子句用于确保仅对包含搜索字符串的行生成代价高昂的XML内容。这可能会返回如下结果:
{“id”:42,“some_列”:“foobar”}
将整行转换为jsonb
,以便在结果中可以看到哪个值属于哪个列
上面可能会返回如下内容:
table_name | table_行
-------------+----------------------------------------
public.foo{“id”:1,“some_列”:“foobar”}
public.bar{“id”:42,“另一列”:“barfoo”}
如果您正在使用IntelliJ将数据库添加到数据库视图,然后右键单击数据库并选择全文搜索,它将列出特定文本的所有表格和所有字段。您是否在寻找工具或链接问题中所示程序的实现?不,这是在所有fie中查找特定值的最简单方法lds/tables。那么你不想使用外部工具吗?如果这是最简单的方法=>ok for a external tool:-)+1 free and simple。如果你想使用结构pg_dump,也可以这样做。如果grep不是你
SELECT * FROM search_columns('86192700'
, array(SELECT DISTINCT a.column_name::name FROM information_schema.columns AS a
INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name)
WHERE
a.column_name iLIKE '%cep%'
AND b.table_type = 'BASE TABLE'
AND b.table_schema = 'public'
)
, array(SELECT b.table_name::name FROM information_schema.columns AS a
INNER JOIN information_schema.tables as b ON (b.table_catalog = a.table_catalog AND b.table_schema = a.table_schema AND b.table_name = a.table_name)
WHERE
a.column_name iLIKE '%cep%'
AND b.table_type = 'BASE TABLE'
AND b.table_schema = 'public')
);
DO $$
DECLARE
value int := 0;
sql text := 'The constructed select statement';
rec1 record;
rec2 record;
BEGIN
DROP TABLE IF EXISTS _x;
CREATE TEMPORARY TABLE _x (
schema_name text,
table_name text,
column_name text,
found text
);
FOR rec1 IN
SELECT table_schema, table_name, column_name
FROM information_schema.columns
WHERE table_name <> '_x'
AND UPPER(column_name) LIKE UPPER('%%')
AND table_schema <> 'pg_catalog'
AND table_schema <> 'information_schema'
AND data_type IN ('character varying', 'text', 'character', 'char', 'varchar')
LOOP
sql := concat('SELECT ', rec1."column_name", ' AS "found" FROM ',rec1."table_schema" , '.',rec1."table_name" , ' WHERE UPPER(',rec1."column_name" , ') LIKE UPPER(''','%my_substring_to_find_goes_here%' , ''')');
RAISE NOTICE '%', sql;
BEGIN
FOR rec2 IN EXECUTE sql LOOP
RAISE NOTICE '%', sql;
INSERT INTO _x VALUES (rec1."table_schema", rec1."table_name", rec1."column_name", rec2."found");
END LOOP;
EXCEPTION WHEN OTHERS THEN
END;
END LOOP;
END; $$;
SELECT * FROM _x;
CREATE OR REPLACE FUNCTION search_whole_db(_like_pattern text)
RETURNS TABLE(_tbl regclass, _ctid tid) AS
$func$
BEGIN
FOR _tbl IN
SELECT c.oid::regclass
FROM pg_class c
JOIN pg_namespace n ON n.oid = relnamespace
WHERE c.relkind = 'r' -- only tables
AND n.nspname !~ '^(pg_|information_schema)' -- exclude system schemas
ORDER BY n.nspname, c.relname
LOOP
RETURN QUERY EXECUTE format(
'SELECT $1, ctid FROM %s t WHERE t::text ~~ %L'
, _tbl, '%' || _like_pattern || '%')
USING _tbl;
END LOOP;
END
$func$ LANGUAGE plpgsql;
SELECT * FROM search_whole_db('mypattern');
select TablesCount(‘StringToSearch’);
CREATE OR REPLACE FUNCTION **TablesCount**(_searchText TEXT)
RETURNS text AS
$$ -- here start procedural part
DECLARE _tname text;
DECLARE cnt int;
BEGIN
FOR _tname IN SELECT table_name FROM information_schema.tables where table_schema='public' and table_type='BASE TABLE' LOOP
cnt= getMatchingCount(_tname,Columnames(_tname,_searchText));
RAISE NOTICE 'Count% ', CONCAT(' ',cnt,' Table name: ', _tname);
END LOOP;
RETURN _tname;
END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification
CREATE OR REPLACE FUNCTION **getMatchingCount**(_tname TEXT, _clause TEXT)
RETURNS int AS
$$
Declare outpt text;
BEGIN
EXECUTE 'Select Count(*) from '||_tname||' where '|| _clause
INTO outpt;
RETURN outpt;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION **Columnames**(_tname text,st text)
RETURNS text AS
$$ -- here start procedural part
DECLARE
_name text;
_helper text;
BEGIN
FOR _name IN SELECT column_name FROM information_schema.Columns WHERE table_name =_tname LOOP
_name=CONCAT('CAST(',_name,' as VarChar)',' like ','''%',st,'%''', ' OR ');
_helper= CONCAT(_helper,_name,' ');
END LOOP;
RETURN CONCAT(_helper, ' 1=2');
END;
$$ -- here finish procedural part
LANGUAGE plpgsql; -- language specification
with found_rows as (
select format('%I.%I', table_schema, table_name) as table_name,
query_to_xml(format('select to_jsonb(t) as table_row
from %I.%I as t
where t::text like ''%%foo%%'' ', table_schema, table_name),
true, false, '') as table_rows
from information_schema.tables
where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
left join xmltable('//table/row'
passing table_rows
columns
table_row text path 'table_row') as x on true
with found_rows as (
select format('%I.%I', table_schema, table_name) as table_name,
query_to_xml(format('select to_jsonb(t) as table_row
from %I.%I as t
where t::text like ''%%foo%%'' ', table_schema, table_name),
true, false, '') as table_rows
from information_schema.tables
where table_schema = 'public'
)
select table_name, x.table_row
from found_rows f
cross join unnest(xpath('/table/row/table_row/text()', table_rows)) as r(data)
select to_jsonb(t)
from some_table t
where t::text like '%foo%';