【问题标题】:Saving file path in PostgreSQL, removes backslashes在 PostgreSQL 中保存文件路径,删除反斜杠
【发布时间】:2019-08-06 14:10:00
【问题描述】:

问题是标题。我们有一个 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
);

从应用程序中,我们发送filenotificationjava.sql.Array,在filelocationfiletargetlocation 参数处具有正确的路径,结果完全没有反冲。我们的问题是:发生了什么事?为什么要删除反斜杠?

编辑:如果我们在函数参数中加入 4 个反斜杠,那么它会输出 1 个反斜杠。如果我们在函数参数中加入 8 个反斜杠,那么它会输出 2 个反斜杠

【问题讨论】:

  • 几乎可以肯定不是。你有任何证据支持你的主张吗? java 和 PostgreSQL 端的值的示例?来自 psql 输出的样本?
  • 我不明白你的问题。我们将“C:\\Users\\kh\\Desktop\\workstuff\\samples\\test_in\\someBook.tif”放入数据库,得到“C:UserkhDesktopworkstuffsamplestest_insomeBook.tif”

标签: java spring postgresql plpgsql pgadmin-4


【解决方案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

【讨论】:

  • 这是有道理的,但问题是我尝试将 4 个反斜杠直接插入数据库。示例:SELECT * FROM public.add_filenotification_array('{"(c:\\\\rs\\me, Path, lang)"}') 返回 156, c\rsme, Path, lang, 2019-03-15 14: 29:22.343519,0
  • @KristófHorváth 你能在db-fiddle.com 中创建一个示例,以便我看看吗?
  • 将它添加到 db-fiddle 但它会导致架构错误。虽然查询确实在我的本地数据库上工作。 db-fiddle.com/f/g1RabAg82UaxxPHzyCNM6Y/1
  • @JSpratt 是的,我还有一个向数据库添加单个文件通知的函数,它按预期添加反斜杠,但是当我编写这个函数(add_filenotification_array)时,它接受一个类型的数组,它不插入反斜杠,除非我在提供的对象属性中放入 4 个反斜杠,即使那样它也只放入一个反斜杠...
  • @KristófHorváth 查看更新的答案,我已经解决了问题。
猜你喜欢
  • 2014-02-04
  • 2013-07-23
  • 1970-01-01
  • 2017-03-16
  • 2023-04-08
  • 2012-08-30
  • 1970-01-01
  • 2016-11-20
  • 1970-01-01
相关资源
最近更新 更多