Генерация HTML из функции PostgreSQL - PullRequest
3 голосов
/ 24 ноября 2010

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

СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ФУНКЦИЮ genhtml2 (текст имени таблицы, текст столбца)
ВОЗВРАЩАЕТ текст AS $ BODY $ ОБЪЯВЛЯЕТ текст результата: = '';searchsql text: = '';var_match text: = '';НАЧАЛО searchsql: = 'SELECT' ||имя столбца ||'ОТ' ||имя таблицы ||'';

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 результат;КОНЕЦ;$ BODY $ LANGUAGE 'plpgsql' IMMUTABLE;

Ответы [ 4 ]

3 голосов
/ 24 ноября 2010

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

2 голосов
/ 17 ноября 2011

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

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

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

2 голосов
/ 24 ноября 2010

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

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

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

0 голосов
/ 02 августа 2018

Отрываясь от других ответов выше, я изменил это, потому что я нашел несколько вопросов в ответах, перечисленных выше, которые включают:

  1. Соединение неверно;неверный псевдоним (т. е. n)
  2. Функция не может обрабатывать нулевые значения
  3. Функция должна генерировать весь HTML-документ с определенным типом HTML-документа

ПРИМЕЧАНИЕ. Поканеобходимость генерировать HTML-документ в postgres не идеальна, есть случаи, когда это может потребоваться сделать.В которой я оказался. Помимо проблем, перечисленных выше, я также включил загрузчик для обработки форматирования и css на столе.Я надеюсь, что это полезно для других.

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 := '';
   varmatch TEXT := '';
   col RECORD; 
   html_doctype TEXT := '<!DOCTYPE html>' || E'\n'; 
   html_meta TEXT := '<meta charset="uft-8">' || E'\n\t' || '<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit="no">' || E'\n'; 
   html_link TEXT := '<link rel="stylesheet" href="boostrapCSSLinkHere.css">' || E'\n';
   html_bscript TEXT := '<script src="bootstraptScriptHere.js"> </script>' || E'\n';
   html_jscript TEXT := '<script src="jQueryScriptHere.js"> </script>' || E'\n'; 
   html_head TEXT := '<html>' || E'\n' || '<head>' || E'\n\t' || html_meta || E'\t' || hmtml_link || E'\t' || html_jscript ||  E'\t' || html_bscript || '</head>' || E'\n'; 
   html_body TEXT := '<body>';
   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
      JOIN pg_namespace AS n ON n.oid = c.relnamespace
      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\n\t' || '<td>' || $QUERY$ || 'coalesce(' || col || ', ''N/A'')' || $QUERY$ || '<td>' $QUERY$;
   END LOOP; 

   header := header || E'\t' || '<tr>' || E'\n'; 
   searchsql := searchsql || ' FROM ' || schemaname || '.' || tablename;
   result := html_doctype || html_head || html_body || E'\n\t' || '<table class="table table-striped table-hover">' || E'\n'; 
   result := result || header; 

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

   RETURN result; 

END; 
$body$
   LANGUAGE 'plpgsql' VOLATILE;
...