使用包含$$字符的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日志中应该有更多的上下文。