我已经使用pg_dump创建了一个sql dump文件。此导出文件包含包含$$字符的函数。使用psql -f <文件名>导入文件没有问题。
如果要使用SQLExec任务使用ant导入文件,则会出现类似以下的异常:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$"
有没有办法导入包含$$的文件?
在postgres日志中,SQLExec任务似乎将$$转换为$,从而导致错误。
错误:字符87处“ $”处或附近的语法错误语句:CREATE FUNCTION process_create_servicenumber()返回触发器语言plpgsql AS $开始,如果(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。
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系列函数符合稳定条件,因为它们的值在事务中不会更改。
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中未转义的特殊字符,例如< > &?美元符号$应该可以。但是我不是蚂蚁专家。PostgreSQL日志中应该有更多的上下文。
;
< > &
$