Ant Sql目标无法创建Postgresql函数

Ant Sql目标无法创建Postgresql函数,ant,Ant,我在名为function.sql的文件中有以下内容: CREATE FUNCTION increment(i integer) RETURNS integer AS $$ BEGIN RETURN i + 1; END; $$ LANGUAGE plpgsql; 我正试图用Ant在本地Postgres(9.3.4)数据库上执行它: <target name = "create" > <sql driver

我在名为function.sql的文件中有以下内容:

CREATE FUNCTION increment(i integer) RETURNS integer AS $$
        BEGIN
                RETURN i + 1;
        END;
$$ LANGUAGE plpgsql;
我正试图用Ant在本地Postgres(9.3.4)数据库上执行它:

<target name = "create" >
    <sql driver="org.postgresql.Driver" url="${db.url}" userid="${db.username}" password="${db.password}">

        <transaction  src="create/functions.sql"/>  

        <classpath>
            <pathelement location="lib/postgresql-9.3-1101.jdbc41.jar"/>
        </classpath>
    </sql>
</target>
但是,如果我直接执行该文件:

psql -d <mydb> functions.sql
psql-d functions.sql

它可以很好地创建函数。我尝试了建议的解决方案,这听起来像是同一个问题,但它们对我不起作用。

错误消息是因为Ant的属性扩展行为看到了
$
,并在到达PostgreSQL之前将其替换为单个
$
(请参见$$expansion一节) 我们可以用几种方法来解决这个问题。按照Ant手册中的建议,将美元字符加倍是可行的,但代价是当文件传递到
psql
客户端时,该文件将不再有效。使用
$BODY$
或(
$which you fairy$
)而不是
$$
来划分函数体,或者在build.xml中将SQL任务的
expandproperties
参数设置为false,我取得了更大的成功

完成后,我们遇到了第二个问题:Ant任务解析您的文件 查找它提供给JDBC的语句。然而,它不是很聪明:它只是 在“;”上拆分人物,即使当他们在身体的中央 函数定义的前半部分(请参阅),因此我们将看到关于未终止字符串(即函数体的前半部分)的错误

我们可以通过使用不同的分隔符并通过
delimiter
delimitertype
参数告诉SQL任务来解决这个问题。以下修补程序将添加到您的项目中 让它为我工作:

diff --git a/build.xml b/build.xml
index 7d8a990..5dbbdc5 100644
--- a/build.xml
+++ b/build.xml
@@ -14,7 +14,7 @@
    </target>

    <target name = "create" >
-               <sql driver="org.postgresql.Driver" url="${db.url}"
userid="${db.username}" password="${db.password}">
+               <sql driver="org.postgresql.Driver" url="${db.url}"
userid="${db.username}" password="${db.password}" delimiter="/* END_STATEMENT */" delimitertype="row" >

                    <transaction  src="create/functions.sql"/>
diff --git a/create/functions.sql b/create/functions.sql
index 3238d3e..1a8518f 100644
--- a/create/functions.sql
+++ b/create/functions.sql
@@ -1,9 +1,9 @@
-CREATE FUNCTION increment(i integer) RETURNS integer AS $$
+CREATE FUNCTION increment(i integer) RETURNS integer AS $BODY$
     BEGIN
             RETURN i + 1;
     END;
-$$ LANGUAGE plpgsql;
-
+$BODY$ LANGUAGE plpgsql;
+/* END_STATEMENT */
diff--git a/build.xml b/build.xml
索引7d8a990..5dbbdc5 100644
---a/build.xml
+++b/build.xml
@@ -14,7 +14,7 @@
-               
+               
diff--git a/create/functions.sqlb/create/functions.sql
索引3238d3e..1a8518f 100644
---a/create/functions.sql
+++b/create/functions.sql
@@ -1,9 +1,9 @@
-创建函数增量(i整数)将整数返回为$$
+CREATE函数increment(i integer)将整数作为$BODY返回$
开始
返回i+1;
结束;
-$$语言plpgsql;
-
+$BODY$语言plpgsql;
+/*结束声明*/
我最初将语句分隔符放在注释中,格式为
--END\u statement
。这只会给人一种工作的假象,因为在解析SQL时,Ant任务会在寻找分隔符之前丢弃这些注释。找不到分隔符它只是将文件的全部内容作为一条语句传递给PostgreSQL,这在您的简单情况下是有效的,但随着函数列表的变长,这并不理想

相反,我使用了C风格的注释,这些注释可以被PostgreSQL识别,但是(目前)不能被Ant任务的解析器识别。当然,如果Ant任务的解析器发生更改,这可能会停止工作


如果<代码>函数。SQL<代码>文件不需要从<代码> PSQL中工作,那么您可以考虑使用任何您喜欢的分隔符。它甚至不必是有效的SQL语法,因为Ant任务会在将语句传递给PostgreSQL之前删除它。

这对我来说很有效!我发现的另外两种解决方案的结合。
diff --git a/build.xml b/build.xml
index 7d8a990..5dbbdc5 100644
--- a/build.xml
+++ b/build.xml
@@ -14,7 +14,7 @@
    </target>

    <target name = "create" >
-               <sql driver="org.postgresql.Driver" url="${db.url}"
userid="${db.username}" password="${db.password}">
+               <sql driver="org.postgresql.Driver" url="${db.url}"
userid="${db.username}" password="${db.password}" delimiter="/* END_STATEMENT */" delimitertype="row" >

                    <transaction  src="create/functions.sql"/>
diff --git a/create/functions.sql b/create/functions.sql
index 3238d3e..1a8518f 100644
--- a/create/functions.sql
+++ b/create/functions.sql
@@ -1,9 +1,9 @@
-CREATE FUNCTION increment(i integer) RETURNS integer AS $$
+CREATE FUNCTION increment(i integer) RETURNS integer AS $BODY$
     BEGIN
             RETURN i + 1;
     END;
-$$ LANGUAGE plpgsql;
-
+$BODY$ LANGUAGE plpgsql;
+/* END_STATEMENT */