Как из папки на компьютере ( не из корневой папки бд ) вставить файл в одно из полей таблицы.
Нужно что-то типа
insert into test(idserial, contenttext)
values (4, нужнаяфункция('D:\html\ex02.xml'));
Знаю, что можно использовать copy, pg_read_file, но не понимаю как.
P.S. Просто вставить текст из файла xml я могу, нужно именно вставлять файл из папки.
Ответ
insert into test(idserial, contenttext)
values (4, pg_read_file('ex02.xml'));
Два момента: pg_read_file разрешено использовать только суперпользователю по соображениям безопасности. Если вы понимаете, что делаете, то обойти это ограничение возможно, например, созданием новой функции от имени суперпользователи и помеченной как security definer. От суперпользователя объявление функции:
CREATE OR REPLACE FUNCTION get_text_document(p_filename CHARACTER VARYING)
RETURNS TEXT AS $$
SELECT pg_read_file($1);
$$ LANGUAGE sql VOLATILE SECURITY DEFINER;
Затем можно её использовать от обычного пользователя
insert into test(idserial, contenttext)
values (4, get_text_document('ex02.xml'));
Второй момент более проблемный: читать так можно только из директории, где лежит сама база или логи. Относительный путь выше по иерархии так же запрещён. Поэтому необходимо либо файл перебросить в нужное место, либо использовать симлинк на директорию (хотя надо бы проверить, вдруг и по симлинку ходить откажется) либо использовать другой способ.
Есть вариант через large object, опять же хранимка от суперпользователя:
create or replace function bytea_import(p_path text, p_result out bytea)
language plpgsql as $$
declare
l_oid oid;
r record;
begin
p_result := '';
select lo_import(p_path) into l_oid;
for r in ( select data
from pg_largeobject
where loid = l_oid
order by pageno ) loop
p_result = p_result || r.data;
end loop;
perform lo_unlink(l_oid);
end;$$;
Оригинальная функция возвращает bytea, не стал это изменять в самой функции. Перекодировать можно вот так:
insert into test(idserial, contenttext)
values (4, convert_from(bytea_import('/etc/fstab'), 'utf8'));
Можно использовать отдельное расширение с базовыми функциями ввода-вывода.
Или можно обратиться опять же к хранимым языкам, но помеченным как небезопасные: pl/perlu или pl/pythonu. Небезопасные они как раз потому, что могут обращаться в том числе к файловой системе беспрепятственно от имени пользователя базы данных. Например
CREATE FUNCTION gettext(url TEXT) RETURNS TEXT
AS $$
import urllib2
try:
f = urllib2.urlopen(url)
return ''.join(f.readlines())
except Exception:
return ""
$$ LANGUAGE plpythonu;
insert into test(idserial, contenttext)
values (4, gettext('file://D:\html\ex02.xml'));
Комментариев нет:
Отправить комментарий