在PostgreSQL中保存文件路径,删除反斜杠

时间:2019-03-15 13:19:52

标签: java spring postgresql plpgsql pgadmin-4

问题是标题。我们有一个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的{​​{1}},并在filenotificationfilelocation参数处使用正确的路径,结果完全没有反弹。我们的问题是:怎么回事?为什么要删除反斜杠?

编辑:如果我们在函数参数中放入4个反斜杠,则输出1个反斜杠。如果我们在函数参数中输入8个反斜杠,则输出2个反斜杠

1 个答案:

答案 0 :(得分:1)

基于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/f/83wBZsztETriNtZGDVXdcN/0