小编典典

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

sql

我已经使用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);
    }
}

阅读 147

收藏
2021-04-14

共1个答案

小编典典

$$只是 美元报价的
最低要求。通过在美元之间放置一个字符串,使它(更多!)不太可能与所包含的文字中的字符串发生冲突:

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$;

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

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

这些都是等效的-除了最后两个偏差较长的时间之外:

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日志中应该有更多的上下文。

2021-04-14