Postgresql:返回结果,而不是在搜索结束时找到

时间:2016-08-03 17:29:05

标签: sql postgresql

我有一个巨大的,可怕的构建数据库,我正在通过它运行查询以查找特定的数据,让我知道它的表和列。有没有办法让查询每次找到而不是在结尾时返回数据?

以下是对那些感兴趣的人的查询

CREATE OR REPLACE FUNCTION search_columns(
needle text,
haystack_tables name[] default '{}',
haystack_schema name[] default '{public}'
)
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)
    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;

--Search in all tables within public schema:
select * from search_columns('E0801');

在特定表格中搜索:

select * from search_columns('foobar','{w}');

搜索从select:

获得的表的子集
select * from 
grep_columns('foobar', array(select table_name::name from information_schema.tables where table_name like 's%'), array['public']);

获取带有相应基表的结果行和ctid:

select * from public.w where ctid='(0,2)';

2 个答案:

答案 0 :(得分:1)

如果您的客户端程序异步显示通知,则可以使用RAISE NOTICE

RAISE NOTICE之前插入RETURN NEXT并在psql中尝试:

...
IF rowctid is not null THEN
  RAISE NOTICE '% % % %', schemaname, tablename, columnname, rowctid;
  RETURN NEXT;
END IF;
...

答案 1 :(得分:0)

您可以使用它声明CURSORFETCH。它需要在显式事务中。

BEGIN;
DECLARE CURSOR mycurs FOR SELECT * FROM search_columns(...);
FETCH FORWARD 5 FROM mycurs;
-- repeat as needed
ROLLBACK;

如果您乐意修改该功能,可以让它返回REFCURSOR。这样做可以允许PostgreSQL改变您的计划以提前返回一些行(尽管这可以使查询的总体成本更高)。对于你的特定例子,这似乎不太可能发生。