使用包含$$字符的SQLExec执行文件

我使用pg_dump创建了一个sql转储文件。 此导出文件包含包含$$字符的函数。 使用psql -f 导入文件没问题。

如果想使用SQLExec任务使用ant导入文件,我会得到一个例外:

org.postgresql.util.PSQLException: ERROR: syntax error at or near "$" 

有没有办法导入包含$$的文件?

在postgres Log中,似乎SQLExec任务将$$转换为$导致错误。

错误:字符处的“$”处或附近的语法错误87语句:创建functionprocess_create_servicenumber()RETURNS触发器LANGUAGE plpgsql AS $ BEGIN IF(TG_OP =’DELETE’)然后返回旧

在这里我的方法

 protected void importNewDbFromDumpFile() { final class SqlExecuter extends SQLExec { public SqlExecuter() { Project project = new Project(); project.init(); setProject(project); setTaskType("sql"); setTaskName("sql"); } } try { SqlExecuter executer = new SqlExecuter(); executer.setSrc(new File(dbDumpFileLocation)); executer.setClasspath(createClasspath()); executer.setEscapeProcessing(true); executer.setDriver("org.postgresql.Driver"); executer.setUrl("jdbc:postgresql://localhost/test"); executer.setPassword("test"); executer.setUserid("manager"); executer.execute(); } catch (Exception e) { log.info("Exception importing database ...", e); } } 

$$只是美元报价的最低限度。 通过在美元之间放一个字符串,使(很多!)不太可能与封闭文字中的字符串冲突:

 CREATE OR REPLACE FUNCTION time_to_sec(timepoint timestamp with time zone) RETURNS bigint LANGUAGE plpgsql AS $BODY$ DECLARE seconds bigint; secondsFromEpoch bigint; secondsFromMidnight bigint; BEGIN secondsFromEpoch = EXTRACT(EPOCH FROM timepoint)::bigint; secondsFromMidnight = EXTRACT(EPOCH FROM CURRENT_TIMESTAMP::date)::bigint; seconds = secondsFromEpoch - secondsFromMidnight; return seconds; END; $BODY$; 

更多建议

  • plpgsql中的赋值运算符是:==未记录,可能在将来的版本中消失。 更多相关问题 。

  • 使用CURRENT_DATE而不是CURRENT_TIMESTAMP::date

  • 这是允许的,但我建议不要在plpgsql中使用混合大小写参数名称。 它们不区分大小写。

  • 最重要的是, 简化

     CREATE OR REPLACE FUNCTION time_to_sec2(timepoint timestamp with time zone) RETURNS bigint LANGUAGE plpgsql STABLE AS $BODY$ BEGIN RETURN EXTRACT(EPOCH FROM timepoint - current_date)::bigint; END; $BODY$; 

    甚至:

     CREATE OR REPLACE FUNCTION time_to_sec3(timepoint timestamp with time zone) RETURNS bigint LANGUAGE sql AS $BODY$ SELECT EXTRACT(EPOCH FROM timepoint - current_date)::bigint; $BODY$; 
  • 可以声明STABLE

另请注意,current_timestamp系列函数符合稳定条件,因为它们的值在事务中不会更改。

  • PostgreSQL中也有一个密切相关的函数age()几乎可以做到,但不完全相同:它返回一个带有标准年和月的“符号”结果。 因此,使用age()表达可以在更长的时间段内产生不同的结果。

这些都是等价的 – 除了最后两个偏离更长时间的情况:

 WITH x(t) AS (VALUES ('2012-07-20 03:51:26+02'::timestamptz)) SELECT time_to_sec(t) AS t1 ,time_to_sec2(t) AS t2 ,time_to_sec3(t) AS t3 ,EXTRACT(EPOCH FROM t - current_date)::bigint AS t4 ,EXTRACT(EPOCH FROM age(t, current_date))::bigint AS t5 -- deviates ,EXTRACT(EPOCH FROM age(t))::bigint * -1 AS t6 -- deviates FROM x; 

至于原始问题:这个PostgreSQL错误消息并不一定意味着问题在于美元符号:

错误:语法错误在“$”或附近

大部分时间都是缺失的; 在那之前。 或者也许是XML中未转义的特殊字符,例如< > & ? 美元符号$应该没问题。 但我不是ant专家。 PostgreSQL日志中应该有更多的上下文。