Сохранение пути к файлу в PostgreSQL, удаление обратной косой черты - PullRequest
0 голосов
/ 15 марта 2019

Проблема в названии.У нас есть база данных postgreSQL, в которой мы хотим сохранить некоторые пути, и база данных удаляет обратную косую черту (\) из пути.

Функция:

CREATE OR REPLACE FUNCTION public.add_filenotification_array(IN fninput public.filenotification_input []) 
RETURNS Table(TYPE public."filenotification") AS 
$$
DECLARE
fn public.filenotification_input;
filenotification public.filenotification;
filenotificationlist public.filenotification [];
BEGIN
FOREACH fn IN ARRAY fninput LOOP
     INSERT INTO public."FileNotification"("FileLocation", "FileTargetLocation", "DocumentLanguage", "LastUpdate", "idStatus", "FileSize") 
 VALUES (fn.filelocation, fn.filetargetlocation, fn.documentlanguage, CURRENT_TIMESTAMP, 0, 0) 
 RETURNING "id", "FileLocation", "FileTargetLocation", "DocumentLanguage", "LastUpdate", "idStatus"
 INTO filenotification.id, filenotification.filelocation, filenotification.filetargetlocation, filenotification.documentlanguage, filenotification.lastupdate, filenotification.idstatus;
 filenotificationlist := array_append(filenotificationlist, filenotification);
END LOOP;
RETURN QUERY
 SELECT * FROM unnest(filenotificationlist::public.filenotification []);
END;
$$
LANGUAGE plpgsql;

Типы файлов:

TYPE filenotification AS (
  "id" integer,
  "filelocation" character varying,
  "filetargetlocation" character varying,
  "documentlanguage" character varying,
  "lastupdate" timestamp,
  "idstatus" integer
  );


TYPE filenotification_input AS (
  "filelocation" character varying,
  "filetargetlocation" character varying,
  "documentlanguage" character varying
);

Из приложения мы отправляем java.sql.Array из filenotification, с правильными путями в параметрах filelocation и filetargetlocation, и результат полностью без зазоров.Наш вопрос: что происходит?Почему он удаляет обратную косую черту?

Редактировать: если мы поместим 4 обратной косой черты в параметр функции, то она выдаст 1 обратную косую черту.Если мы поместим 8 обратных слешей в параметр функции, то получится 2 обратных слеша

1 Ответ

1 голос
/ 15 марта 2019

Хорошо, основываясь на dbfiddle, я вижу, в чем проблема.(Кстати, там не нравится указание доллара, поэтому вы не можете запустить его. Вам просто нужно заменить $$ на ', чтобы заключить его в строку, и он будет работать.)

Ваш ввод '{"(c:\\\\\\\rs\\me, Path, lang)"}'.Это массив типа.

Давайте рассмотрим простой тип: CREATE TYPE public.t AS (txt TEXT).Когда вы выбираете тип в виде строки, а не с расширенными полями, любые «специальные» символы будут экранированы.

Итак: SELECT ROW('C:\temp')::public.t возвращает ("C:\\temp"), а расширение его с помощью SELECT (ROW('C:\temp')::public.t).* возвращает C:\temp.

Ваш ввод является строкой (он использует запись (data1,data2,etc), котораяряд буквальный и нерасширенный), поэтому все обратные слэши экранированы.Часть пути вашей расширенной строки (SELECT ('(c:\\\\\\\rs\\me, Path, lang)'::public.filenotification_input).*) будет иметь вид c:\\\rs\me.

Однако есть еще один уровень экранирования: факт, что данные находятся в массиве.Как и в случае нерасширенной строки, специальные символы будут экранированы в массиве.Выполнение SELECT ARRAY['C:\temp'] возвращает ["C:\\temp"].

Сложите их вместе, и у вас есть обратные слэши, нуждающиеся в экранировании в вашем ряду, и каждый из них затем должен экранироваться в массиве.Таким образом, чтобы получить одну обратную косую черту в «обычном» тексте, вы должны экранировать ее в строке (\\), а затем экранировать каждую из них в массиве (\\\\).

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

Запустите это и посмотрите на различные выходные данные: https://www.db -fiddle.com / ж / 83wBZsztETriNtZGDVXdcN / 0

...