通过Maven创建测试数据库时Postgresql触发分隔符问题

时间:2016-07-18 11:05:52

标签: postgresql maven delimiter sql-scripts

我目前正在开发一个使用PostgreSQL数据库的Java应用程序。作为Maven构建的一部分,我通过删除测试数据库,再次创建它并运行所有SQL脚本来测试数据库SQL脚本。

在Maven方面,我使用"sql-maven-plugin"插件来执行这些数据库命令,一切正常,直到我执行create_triggers.sql脚本。这是因为触发器函数中有分号字符(;)。我尝试了不同的东西,而我目前的(hacky)解决方案是将 SQL Maven插件<delimiter>设置为: -

<delimiter>;--</delimiter>

这将分隔符指定为分号,后面紧跟SQL注释。这意味着我可以在pgAdmin和maven中运行create_trigger.sql脚本。例如

create_scripts.sql

(注意每个陈述后的;--

DROP TRIGGER IF EXISTS refresh_updated_on_description ON my_table;--

/* Example trigger which updates `updated` field when `description` changes */

CREATE OR REPLACE FUNCTION refresh_updated()  
RETURNS TRIGGER AS $$
BEGIN
   IF (NEW.description != OLD.description
   THEN
      NEW.updatedn = now(); 
      RETURN NEW;
   ELSE
      RETURN NEW;
   END IF;

END;
$$ language 'plpgsql';--

CREATE TRIGGER refresh_updated_on_description BEFORE UPDATE ON my_table FOR EACH ROW EXECUTE PROCEDURE refresh_updated();--

的pom.xml

(请注意上一个<delimiter>;--</delimiter>部分中的<execution>元素)             ...

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>sql-maven-plugin</artifactId>
            <version>1.5</version>
            <dependencies>
                <dependency>
                    <groupId>org.postgresql</groupId>
                    <artifactId>postgresql</artifactId>
                    <version>9.4-1201-jdbc41</version>
                </dependency>
            </dependencies>
            <configuration>
                <driver>org.postgresql.Driver</driver>
                <username>${postgres.username}</username>
                <password>${postgres.password}</password>
                <skip>${maven.test.skip}</skip>
            </configuration>
            <executions>
                <execution>
                    <id>drop-and-create-test-database</id>
                    <phase>pre-integration-test</phase>
                    <goals><goal>execute</goal></goals>
                    <configuration>
                        <url>${postgresql.test.db.server}</url>
                        <autocommit>true</autocommit>
                        <sqlCommand>
                            drop database if exists myapp_test;
                            create database myapp_test;
                        </sqlCommand>
                    </configuration>
                </execution>
                <execution>
                    <id>run-database-scripts-on-test-db</id>
                    <phase>pre-integration-test</phase>
                    <goals><goal>execute</goal></goals>
                    <configuration>
                        <url>${postgresql.test.db.database}</url>
                        <srcFiles>
                            <srcFile>${basedir}/src/main/resources/sql/create_tables.sql</srcFile>
                        </srcFiles>
                    </configuration>
                </execution>
                <execution>
                    <id>run-database-create-complex-scripts-on-test-db</id>
                    <phase>pre-integration-test</phase>
                    <goals><goal>execute</goal></goals>
                    <configuration>
                        <url>${postgresql.test.db.database}</url>
                        <delimiter>;--</delimiter>
                        <srcFiles>
                            <srcFile>${basedir}/src/main/resources/sql/create_triggers.sql</srcFile>
                        </srcFiles>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        ...

然而,这感觉就像一个hacky解决方案,因为我只能使用多行符号(/* some comment ... */)来声明create_triggers.sql文件中的注释。我还需要记住在每个SQL语句之后包含;--以及此文件 - 否则maven构建将失败(但在pgAdmin中运行正常)。

是否有更好的方法在脚本中指定分隔符?

1 个答案:

答案 0 :(得分:0)

请参考以下问题:Error when executing mvn sql:execute

该解决方案要求更改配置,以便分隔符必须位于其自己的行上:

<delimiterType>row</delimiterType>

然后按以下方式结束功能:

  end if;
end;
$$ language 'plpgsql'
;

并且解析器一直读取直到找到结尾的分号为止。

您必须修改所有其他sql语句,以在每个分号之前添加回车符。