我需要以编程方式执行SQL脚本。该脚本定义了一个函数,该函数根据其版本升级 postgreSQL 数据库。它看起来像这样:
create or replace function update_auto_increment(version varchar(20)) returns integer
as $$
declare
v integer;
begin
v := cast(version as int);
if v < 590 then
-- some upgrade code here
v := 590;
raise notice 'Updated base to version %', v;
end if;
return v;
end;
$$ language plpgsql;
select update_auto_increment(value) from info where name = 'version';
drop function update_auto_increment(varchar(20));
然后我准备一个 ANT 任务并执行它:
SQLExec task = new SQLExec();
Project project = new Project();
project.init();
task.setProject(project);
task.setTaskType("sql");
task.setTaskName("sql");
task.setSrc(new File("updateScript.sql"));
task.setDriver(driver);
task.setPassword(password);
task.setUserid(username);
task.setUrl(connectionURL);
task.execute();
并且执行过程在遇到$$时失败:
org.postgresql.util.PSQLException: ERROR: syntax error (near: "$")
position: 91
at org.apache.tools.ant.taskdefs.SQLExec.execute(SQLExec.java:672)
(错误消息已本地化,我尝试将其翻译成英文)。所以,问题是:如何以编程方式执行包含函数定义的 SQL 脚本?
SQLExec 正在按 ;
拆分语句,这是 SQL 中的默认语句终止字符。
在您的情况下,不应发生拆分。
您可以尝试使用类似以下内容:
task.setDelimiterType(SQLExec.DelimiterType.ROW);
task.setDelimiter("/");
然后在一行上用/
分隔文件中的 SQL 语句:
create or replace function update_auto_increment(version varchar(20)) returns integer
as $$
declare
v integer;
begin
v := cast(version as int);
if v < 590 then
-- some upgrade code here
v := 590;
raise notice 'Updated base to version %', v;
end if;
return v;
end;
$$ language plpgsql;
/
select update_auto_increment(value) from info where name = 'version'
/
drop function update_auto_increment(varchar(20))
/
除了a_horse_with_no_name的答案外,您还需要将$$
替换为标签形式$foo$
。
更多关于美元报价字符串的信息:http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-DOLLAR-QUOTING