2016-05-12 8 views
0

私の会社はデータベースからのデータを使用して文書を生成し始めます。私は文書のテキストを吐き出す機能を設計しています。これらの文書には、数百の列を持つ複数の表から取られたデータが含まれている必要があり、必ず一部のレコードにはデータが欠落しています。ダイナミッククエリの結果をテーブルとして取得するには?

nullフィールドを取り、小さなエラーメッセージで置き換えて、データが欠落していることをエンドユーザーに明確にする関数を作成しようとしています。エンドユーザーはバックエンドに全く慣れていないので、これらのメッセージがわかりやすいものを参照するようにします。

私のソリューションはかなりシンプルですが、私の人生のために私はそれを働かせることはできません。レコード識別子、テーブル名は、関数内のパラメータとして設定されます。この関数は、指定された表の各列の名前をループし、一連の大文字小文字を含むクエリを作成します。ループが完了すると、識別子が追加され、クエリが実行され、呼び出し元の関数に結果が返されます。

親クエリで特定のデータを簡単に参照する必要があるため、読んでいるにもかかわらず、すべての結果を含む単一の列/行があります。 。私は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; 
+0

あなたはそんなにトラブルを後藤なぜ代わりにヌルのユーザーに何かを表示したい場合は?これまでのプラットフォームで使用しているビューでこれを行うのはずっと簡単です – e4c5

答えて

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';