我使用pg_dump创建了一个sql转储文件。此导出文件包含包含$$字符的函数。使用psql -f<导入文件没问题文件名>
如果想使用SQLExec任务使用ant导入文件,我会收到如下异常:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$"
有没有办法导入包含$$的文件?
在postgres Log中,似乎SQLExec任务将$$转换为$导致错误。
错误:字符87处的“$”处或附近的语法错误 声明:创建功能process_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);
}
}
答案 0 :(得分:2)
$$
只是dollar-quoting的最低要求。通过在美元之间放置一个字符串,使(很多!)不太可能与封闭文字中的字符串发生冲突:
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中的赋值运算符为:=
。 =
没有文档,可能会在将来的版本中消失。更多信息请见related question。
使用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()
几乎可以做到,但不完全相同:它返回一个带有标准年和月的“符号”结果。因此,使用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日志中应该有更多的上下文。