2010-11-24 2 views
2

Может ли кто-нибудь помочь мне с этим. У меня есть задача обрезать функцию, которая будет генерировать html-таблицы из заданного имени таблицы в postgreSQL (plpgsql language). Я написал это, но это далеко не то, что мне нужно. Он будет генерировать таблицу для столбцов, которые я бы дал (теперь только один), но мне нужно указать только имя таблицы.Создать HTML из функции PostgreSQL

CREATE OR REPLACE FUNCTION genhtml2 (имя_таблицы текст, ColumnName текст)
возвращает текст AS $ ТЕЛА $ DECLARE результирующий текст: = ''; searchsql text: = ''; var_match text: = ''; BEGIN searchsql: = 'SELECT' || columnname || ' FROM' || tablename || '';

result := '<table>'; 
FOR var_match IN EXECUTE(searchsql) LOOP 
    IF result > '' THEN 
     result := result || '<tr>' || var_match || '</tr>'; 
    END IF; 
END LOOP; 
result := result || '</table>'; 

RETURN result; КОНЕЦ; $ BODY $ LANGUAGE 'plpgsql' IMMUTABLE;

+0

НЕ используйте квалификатор `IMMUTABLE` с этой функцией! PostgreSQL может сделать небезопасную оптимизацию. Читайте: http://www.postgresql.org/docs/9.0/interactive/xfunc-volatility.html – intgr 2010-11-24 13:32:11

+0

Знаете ли вы, что psql имеет переключатель -H html? `psql -H -c'select * from table'.` – 2010-11-24 19:13:49

ответ

1

Сначала вы можете выполнить поиск калогов для столбцов в таблице, а затем использовать их для генерации запроса и для установки заголовка таблицы.

colsql := $QUERY$SELECT attname 
       FROM pg_attribute AS a JOIN pg_class AS c ON a.attrelid = c.oid 
       WHERE c.relname = '$QUERY$ 
      || tablename || $QUERY$' AND attnum > 0;$QUERY$; 

header := ''; 
searchsql := $QUERY$SELECT ''$QUERY$; 
FOR col IN EXECUTE colsql LOOP 
    header := header || '<th>' || col || '</th>'; 
    searchsql := searchsql || $QUERY$||'<td>'||$QUERY$ || col; 
END LOOP; 

searchsql := searchsql || ' FROM ' || tablename; 

-- rest of your function here 

Очевидно, что это становится грязным и ломкими быстро ...

3

Я вполне уверен, что вы не должны этого делать, потому что это потенциальный кошмар обслуживания. Лучшее, что нужно сделать, это вернуть результаты строки в любое приложение или другой слой и работать оттуда в направлении html.

+0

Я бы, безусловно, был бы, но задача это сделать именно на plpgsql, и я не могу изменить это :( – Adomas 2010-11-24 09:40:50

1

Вот модифицированная версия, которая работает с несколькими столбцами, используя текст [] массив для имен столбцов. Он также печатает новые строки и вкладки для форматирования вывода.

CREATE OR REPLACE FUNCTION genhtml(text, text, text, text[]) 
    RETURNS text AS $BODY$ 

DECLARE 
    schemaname ALIAS FOR $1; 
    tablename ALIAS FOR $2; 
    tabletype ALIAS FOR $3; 
    columnnames ALIAS FOR $4; 
    result TEXT := ''; 
    searchsql TEXT := ''; 
    var_match TEXT := ''; 
    col RECORD; 
    header TEXT; 

BEGIN 

    header := E'\t' || '<tr>' || E'\n'; 
    searchsql := $QUERY$SELECT ''$QUERY$; 
    FOR col IN SELECT attname 
    FROM pg_attribute AS a 
    JOIN pg_class AS c ON a.attrelid = c.oid 
    WHERE c.relname = tablename 
     AND n.nspname = schemaname 
     AND c.relkind = tabletype 
     AND attnum > 0 
     AND attname = ANY(columnnames) 
    LOOP 
    header := header || E'\t\t' || '<th>' || col || '</th>' || E'\n'; 
    searchsql := searchsql || $QUERY$ || E'\n\t\t' || '<td>' || $QUERY$ || col ||  $QUERY$ || '</td>' $QUERY$; 
    END LOOP; 
    header := header || E'\t' || '</tr>' || E'\n'; 

    searchsql := searchsql || ' FROM ' || schemaname || '.' || tablename; 

    result := '<table>' || E'\n'; 
    result := result || header; 
    FOR var_match IN EXECUTE(searchsql) LOOP 
    IF result > '' THEN 
     result := result || E'\t' || '<tr>' || var_match || E'\n\t' || '</tr>' || E'\n'; 
    END IF; 
    END LOOP; 
    result := result || '</table>' || E'\n'; 

    RETURN result; 

END; 
$BODY$ 
    LANGUAGE 'plpgsql' VOLATILE; 

Вызов функции с чем-то вроде:

SELECT genhtml('public', 'tablenamehere', 'r', ARRAY['col1', 'col2', 'col3']); 

'г' для обычных таблиц. Если вы используете VIEW, измените его на «v».

Смежные вопросы