如何使用Play框架中的evolutions在PostgreSQL中创建函数?

lkaoscv7  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(2)|浏览(130)

使用Play Framework 2.1

我在我的进化中定义了以下SQL:

CREATE OR REPLACE FUNCTION idx(myArray anyarray, myElement anyelement) RETURNS int AS $$
 SELECT i FROM (
  SELECT generate_series(array_lower(myArray,1),array_upper(myArray,1))
 ) g(i)
 WHERE myArray[i] = anyElement
 LIMIT 1; $$ LANGUAGE sql IMMUTABLE;

字符串
当我执行evolution时,我得到以下错误:

We got the following error: ERROR: unterminated dollar-quoted string at or near 
"$$ SELECT i FROM ( SELECT generate_series(array_lower(myArray,1),
 array_upper(myArray,1)) ) g(i) WHERE myArray[i] = anyElement LIMIT 1" Position:
 87 [ERROR:0, SQLSTATE:42601], while trying to run this SQL script:


我使用的是PostgreSQL驱动程序版本9.1-901.jdbc4。
我查看了postgres查询日志,发现Play正在尝试执行以下操作:

LOG:  execute <unnamed>: insert into play_evolutions values($1, $2, $3, $4, $5, $6, $7)
PST DETAIL:  parameters: $1 = '1',
                         $2 = 'c834d463ebd9916b0a3388040300a0926514faef',
                         $3 = '2013-03-05 00:00:00',
                         $4 = '-- THE EVOLUTION UP STATEMENTS GO HERE',
                         $5 = '-- THE EVOLUTION DOWN STATEMENTS GO HERE',
                         $6 = 'applying_up',
                         $7 = ''


所以,由于某种原因,Play试图在没有正确转义的情况下将SQL插入到文本列中。有没有其他人找到了解决这个问题的方法?你认为这是JDBC问题而不是Play问题?还有,有没有人让Liquibase在Play 2.1上工作?
另外,仅仅将$$改为'也不起作用。在这种情况下,我们会得到一个不同的错误,但我们仍然不能执行进化。
编辑:我添加了一个全新的游戏项目的例子。请下载:http://elijah.zupancic.name/files/play_evolution_problem.tar.gz
为了让这个例子工作,你需要创建一个新的数据库,如evolution 1.sql的第一条评论所示。然后你需要配置你的conf/application.conf,以正确的端口和正确的用户连接到postgres。
我刚刚做了一个实验,我尝试将create函数sql完全插入到play框架之外。
事实证明,它是非常可复制的。
编辑:原来我不能在Java中复制它。

1aaf6o9v

1aaf6o9v1#

这是Play解析evolutions的方式的一个工件。由于它解析每个语句上的子程序,它不能处理存储过程定义。这个问题在Play 2.1中已经得到解决,它允许您通过将子程序加倍来指定嵌入的子程序。例如,请参阅https://github.com/playframework/Play20/pull/649
使用;;为我解决了一个类似的问题,使用Play 2.1。我建议你重新定义你的进化如下,然后再试一次:

CREATE OR REPLACE FUNCTION idx(myArray anyarray, myElement anyelement) RETURNS int AS $$
 SELECT i FROM (
  SELECT generate_series(array_lower(myArray,1),array_upper(myArray,1))
 ) g(i)
 WHERE myArray[i] = anyElement
 LIMIT 1;; $$ LANGUAGE sql IMMUTABLE;

字符串

drkbr07n

drkbr07n2#

你可以在return语句中使用一个美元符号。简单的例子:

CREATE OR REPLACE FUNCTION sys_extract_utc(
    time_in timestamp with time zone)
    RETURNS timestamp without time zone
    LANGUAGE 'sql'
    PARALLEL SAFE
    return $1 at time zone 'UTC';

字符串
Postgres文档链接:https://www.postgresql.org/docs/current/sql-createfunction.html

相关问题