将动态查询的结果作为表格?

时间:2016-05-12 18:08:25

标签: postgresql

我的公司将开始使用我们数据库中的数据生成文档,我正在设计将吐出文档文本的函数。这些文档需要包含从多个表中获取的数据,其中有数百列,并且总会有一些记录丢失数据。

我正在尝试创建一个将占用空字段的函数,并将其替换为一个小错误消息,使最终用户清楚地知道缺少一些数据。由于最终用户完全不熟悉后端,我希望这些消息能够引用他们可理解的内容。

我的解决方案非常简单,但对于我的生活,我无法让它发挥作用。记录标识符,表名称设置为函数中的参数。然后,该函数循环遍历指定表中每个列的名称,构建包含大量case语句的查询。循环完成后,将附加标识符,然后执行查询,将结果返回给调用函数。

尽管阅读了很多,但我能做的最好的是包含所有结果的单个列/行 - 对我来说根本没用,因为我需要能够在父查询中轻松引用特定的数据片段。我是Postgres的初学者,文档太复杂,我无法理解,任何帮助都将不胜感激。

-- Function: data_handler(text, text)

-- DROP FUNCTION data_handler(text, text);

CREATE OR REPLACE FUNCTION data_handler(target_uri text, target_table TEXT)
  RETURNS SETOF record AS
$BODY$
DECLARE
c text;
strSQL text;
site_only text;
result record;

BEGIN
--We need the schema for strSQL but the loop needs just the table name.  
site_only = split_part(target_table, '.', 2);

FOR c IN
SELECT column_name 
FROM information_schema.columns
WHERE table_name = site_only
LOOP

    strSQL = concat(strSQL, chr(10), '(SELECT CASE WHEN ', c::text, '::text IS NULL THEN concat(', chr(39), '<Error:', chr(39), ', (SELECT lkp_value FROM alb_cr.lkp_field_values WHERE column_name = ', chr(39), c::text, chr(39), ')::text, ', chr(39), ' value not found>', chr(39), ')::text ELSE ', 
    c::text, '::text END AS ', c::text, '_convert) AS ', c::text, ',');

END LOOP;
strSQL = LEFT(strSQL, character_length(strSQL) - 1);
strSQL = concat('SELECT ', strSQL, ' FROM ', target_table, ' WHERE nm_site_id = ', chr(39), target_uri, chr(39));   

RETURN QUERY EXECUTE strSQL;

RAISE NOTICE 'strSQL: %', strSQL;
--RETURN strSQL;
--RETURN QUERY EXECUTE format('SELECT ' || strSQL || 'FROM %s WHERE nm_site_id = $1', pg_typeof(target_table)) USING target_uri;

END
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION data_handler(text, text)
  OWNER TO inti;

1 个答案:

答案 0 :(得分:0)

您也可以在以下示例中为模式nullsbegone创建视图:

-- create the schema to hold the views
create schema if not exists nullsbegone;

-- create a function to create the views (any and all that you might need)
create or replace function nullsbegone.f_make_view_of(p_tablename text) returns void as $f$
begin
  execute ($$
create or replace view nullsbegone.$$||(select relname from pg_class where oid = $1::regclass)||$$
  returns void as
  select $$||array_to_string(array(
select case when not attnotnull then 'COALESCE('||quote_ident(attname)||$$::text, (SELECT '<Error:'''||lkp_value||''' value not found>' FROM alb_cr.lkp_field_values
                                                                                   WHERE column_name = $$||quote_literal(attname)||$$)) AS $$
       else '' end || quote_ident(attname)
from pg_attribute
where attrelid = $1::regclass and attnum > 0 order by attnum
), E', \n')||$$
from $$||$1);
end;$f$ language plpgsql;

-- create the view based on a given table
select nullsbegone.f_make_view_of('yourschema.yourtable');

-- select from your view as if you were selecting from the actual table
select * from nullsbegone.yourtable
where nm_site_id = 'yoursite';