postgres 迁移错误;未终止的美元引号字符串

Posted

技术标签:

【中文标题】postgres 迁移错误;未终止的美元引号字符串【英文标题】:postgres migration error; unterminated dollar-quoted string 【发布时间】:2013-12-10 16:03:35 【问题描述】:

这有点奇怪,谁能帮我指出这个函数可能出错的地方。 我有一个类似于

的功能
CREATE FUNCTION check_password(uname TEXT, pass TEXT)
RETURNS BOOLEAN AS $$
DECLARE passed BOOLEAN;
BEGIN
        SELECT  (pwd = $2) INTO passed
        FROM    pwds
        WHERE   username = $1;

        RETURN passed;
END;

$$  LANGUAGE plpgsql

当我直接在 pgAdmin sql 控制台中运行它时,没有错误,但使用 db-migration-maven-plugin 在迁移脚本中运行它时出现错误。

Error executing: CREATE FUNCTION check_password(uname TEXT, pass TEXT) 
                 RETURNS BOOLEAN AS $$ DECLARE passed BOOLEAN
org.postgresql.util.PSQLException: ERROR: unterminated dollar-quoted 
                        string at or near "$$ DECLARE passed BOOLEAN"
Position: 74

【问题讨论】:

对不起,现在遇到同样的问题。你找到解决方法了吗? 我避免一起编写长函数。这是迁移软件(碳五)的问题。我想对其进行一些更改,因为它是开源的,但没有时间。 我在使用使用 Redshift JDBC 驱动程序的 Aqua Data Studio 时收到了类似的错误消息。就我而言,解决方法是转到“选项”并取消勾选';语句分隔符'。解析器似乎假设第一个分号是整个函数定义的结尾,它还没有看到结束 $$ 。当未选中该框时,您的示例函数在我的系统(9.5 版)上创建时没有错误。用';声明分隔符'打勾,我得到了同样的错误。希望对您有所帮助。 【参考方案1】:

迁移脚本生成的 SQL 中可能包含某种 $$ 引号,这些引号在某处被解释为字符串。

一个快速而肮脏的解决方法可能是将$$ 更改为$func$ 甚至$check_password$,尽管可能还有其他函数会遇到同样的问题。

更好、更长期的方法是找到违规的$$

【讨论】:

一开始我也是这么想的,把 $$ 改成 $func$ 但还是没用 @ivan_d_coder:它失败并显示完全相同的错误消息,还是在不同的位置? 仔细检查正在获取输出的 SQL。整个迁移的事情。那里一定有你没有注意到的未终止的字符串,或者其他一些使字符串看起来没有终止的语法错误。 好吧,我发现了一件有趣的事情,迁移插件 (db-migration-maven-plugin) 逐部分运行函数,而不是使用 $$ 指定的整体。所以发生的事情是它在遇到终止后立即执行语句,而不是将整个块包装在 $$ $$ 中并将其作为一个执行。我现在想知道的是如何让它执行$$......$$块中的整个语句。【参考方案2】:

@ivanorone: db-migration-maven-plugin 存在一个错误:https://code.google.com/p/c5-db-migration/issues/detail?id=9 包含一个补丁,但查看它的来源,它并没有真正正确地解决问题。除此之外,该项目似乎处于闲置状态(最后一次提交是 2010 年)。

我正在尝试使用另一个插件,Flyway:http://flywaydb.org/ 切换到它非常简单,到目前为止它运行良好。

【讨论】:

我同意,flywaydb 似乎比 carbon5 b-migration-maven-plugin 更活跃。我没有认真对待它,但很快就会看看【参考方案3】:

Grails Database Migration Plugin的解决方案

changeSet(author: "...", id: "...") 
    sql(splitStatements: false, '''
        CREATE FUNCTION trigger_func() RETURNS TRIGGER AS $$
        DECLARE var text;
        BEGIN
        ...
        END $$ LANGUAGE plpgsql;
    ''')

【讨论】:

【参考方案4】:

将您的查询作为单个批次执行(提示:使用 ctrl+F5)。当我在 Postgres SQl(Greenplum 接口)中运行您的查询时,我遇到了与上述类似的错误。我发现 db 正在通过根据我们的查询(分号)中的终止来拆分查询来执行查询。由于我们已经在查询中终止了三次,它会一条一条地执行它。因此,要将其作为一个整体批处理运行,就像在您的执行选项中使用作为单个批处理一样执行。

希望对你有帮助:):)

【讨论】:

太棒了。工作得很好。【参考方案5】:

最好的解决方案似乎是告诉插件仅在分号位于新行时才接受分号作为分隔符。 这在您需要定义这样的代码块时效果很好。

参考:sql-maven-plugin with multiple delimiters

【讨论】:

以上是关于postgres 迁移错误;未终止的美元引号字符串的主要内容,如果未能解决你的问题,请参考以下文章

错误:在“$BODY$”处或附近未终止的美元引号字符串

[Amazon](500310) 无效操作:"$$" 处或附近未终止的美元引号字符串

Liquibase : $BODY$ 或附近的未终止的美元引号字符串

带有测试容器的未终止美元报价初始化脚本

Postgres:使用psycopg2或附近未终止的引用字符串

我得到美元符号未终止