Sql 函数动态查找列名
在下面提供的函数Sql 函数动态查找列名,sql,postgresql,plpgsql,dynamic-sql,Sql,Postgresql,Plpgsql,Dynamic Sql,在下面提供的函数find\u value\u In_table()中,我试图找到任何列的名称,这些列的记录中的列值与字符串“255.255.255.255”匹配 简而言之,是这样的: SELECT column_name FROM dynamic_table WHERE column_value = '255.255.255.255'; 注: 表名作为参数传递给函数,因此称为“dynamic_table” 我试图确定列的名称,而不是数据值 这是第一步。稍后我还将参数化列_值。我知道
find\u value\u In_table()
中,我试图找到任何列的名称,这些列的记录中的列值与字符串“255.255.255.255”匹配
简而言之,是这样的:
SELECT column_name
FROM dynamic_table
WHERE column_value = '255.255.255.255';
注:
- 表名作为参数传递给函数,因此称为“dynamic_table”
- 我试图确定列的名称,而不是数据值
“255.255.255.255”
,我想通过查找存储此值的表和列名来证明此函数的功能
这一切的目的是:我有一个大的数据库,我是复古工程。我知道它包含应用程序的一些配置参数。在当前配置中,我知道其中一些参数的精确值(见应用程序配置GUI:例如计算机名、ip地址)。我想浏览整个数据库,以确定哪些表存储此配置信息
我一直在构建函数find_value()
,以返回这些线索
如何做到这一点
create or replace function find_all_columns(tablename in text)
return setof record as
$func$
declare r record;
begin
return select a.attname as "Column",
pg_catalog.format_type(a.atttypid, a.atttypmod) as "Datatype"
from
pg_catalog.pg_attribute a
where
a.attnum > 0
and not a.attisdropped
and a.attrelid = ( select c.oid from pg_catalog.pg_class c left join pg_catalog.pg_namespace n on n.oid = c.relnamespace where c.relname ~ '^(' || quote_ident(tablename) || ')$' and pg_catalog.pg_table_is_visible(c.oid);
end loop;
end;
$func$ language 'plpgsql';
create or replace function find_value_in_table(tablename text)
returns setof record as
$func$
declare r record;
return select
begin
for r in (select find_all_columns(tablename)) loop
return select * from tablename t where t... = "255.255.255.255" /* here column would be the value in the record: r.Column*/
end loop;
end;
$func$ language 'plpgsql';
create or replace function find_tables_name(_username text)
returns setof record as
$func$
declare
tbl text;
begin
for tbl in
select t.tablename from pg_tables t
where t.tableowner = _username and t.schemaname = 'public'
loop
return quote_ident(tbl);
end loop;
end;
$func$ language 'plpgsql';
create or replace function find_value(_username text, valuetofind text)
returns setof record as
$func$
declare r record;
begin
for r in (select find_tables_name(_username)) loop
return find_value_in_table( r.tablename );
end loop;
end;
$func$ language 'plpgsql';
实现这一点的一种基本方法是进行纯文本转储,并使用您选择的编辑器(在我的例子中是vim)搜索字符串 但是这个函数做得更好。:) 电话: 返回:
tbl | col | typ
-----------------+-------------+------
event.eventkat | eventkat | text
public.foo | description | text
public.bar | filter | text
使用PostgreSQL 9.1进行测试
要点
- 该功能是一站式的
- 我构建了一个选项来搜索部分值(
)。默认设置是搜索整列\u part
- 我在整行上构建了一个快速测试,以消除那些根本没有
的表。为此,我使用PostgreSQL的功能将整行快速转换为文本。这将使函数更快—除非所有或几乎所有表都符合条件,或者表只有一列值find
- 我将返回类型定义为
,并立即分配隐式定义的变量返回表(tbl text、col text、typ text)
、tbl
和col
。因此,我不需要额外的变量,当列符合条件时,我可以typ
立即返回NEXT
- 在这里大量使用
!这是最快的选择,因为您只关心该列是否具有该值存在
- 使用
(或简称如
)代替正则表达式。更简单,更快~
- I
立即输入所有标识符quote_ident()
- 是工具性的
SELECT * FROM find_columns('postgres', '255.255.255.255');
SELECT * FROM find_columns('fadmin', '255.255.255.255', TRUE);
tbl | col | typ
-----------------+-------------+------
event.eventkat | eventkat | text
public.foo | description | text
public.bar | filter | text