iBatis 的 ScriptRunner 无法执行完全有效的 SQL 脚本
Posted
技术标签:
【中文标题】iBatis 的 ScriptRunner 无法执行完全有效的 SQL 脚本【英文标题】:iBatis' ScriptRunner Is Failing To Execute a Perfectly Valid SQL Script 【发布时间】:2021-01-11 19:30:08 【问题描述】:我正在使用 iBatis 的 ScriptRunner 在 Oracle 数据库上执行脚本。第一个脚本执行得很好,但是其中有触发器的第二个脚本返回:
Cause: java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement
在 SQL Developer 上执行返回此错误的脚本部分没有任何错误:
.
.
.
create table MG_MSGALR
(
ID VARCHAR2(30) not null,
V_GRAV VARCHAR2(3),
constraint PK_MG_MSGALR primary key (ID) using index tablespace B_INDEX
);
CREATE OR REPLACE TRIGGER UC_JAR_LST_TRIGGER
BEFORE INSERT
ON UC_JAR_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_JAR_LST_SEQ.nextval INTO :NEW.ID FROM dual;
END;
/
CREATE OR REPLACE TRIGGER UC_UPD_LST_TRIGGER
BEFORE INSERT
ON UC_UPD_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_UPD_LST_SEQ.nextval INTO :NEW.ID FROM dual;
END;
/
这是我执行脚本的方式:
Boolean procedure = StringUtils.endsWith(FilenameUtils.getBaseName(file.getName()), "procedure") || StringUtils.endsWith(FilenameUtils.getBaseName(file.getName()), "trigger");
runner.setSendFullScript(procedure);
runner.runScript(new FileReader(file));
我注意到,即使脚本中有触发器,布尔过程的值也始终为 false,因此我尝试强制 ScriptRunner 将其作为完整脚本发送,以查看它是否通过,我得到以下信息而是错误:
CREATE OR REPLACE TRIGGER UC_UPD_LST_TRIGGER
BEFORE INSERT
ON UC_UPD_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_UPD_LST_SEQ.nextval INTO :NEW.ID FROM dual;
END;
/
. Cause: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
有人可以告诉我我在这里做错了什么吗?应该在应该开始创建触发器之前在文件中添加某种分隔符(现在位于文件的最后)。
【问题讨论】:
【参考方案1】:以防其他人遇到同样的问题。当您有一个混合脚本(这意味着它同时具有普通查询和过程或触发器),并且如果您尝试使用来自 Java 的 myBatis 执行它,您需要做的就是将所有过程留在您的末尾脚本并在它们之前和之后放置分隔符,让 SQL 知道它应该作为块执行,而不是逐行执行。所以这就是我添加分隔符的方式:
-- Change the delimiter to '$'
-- @DELIMITER $
CREATE OR REPLACE TRIGGER UC_JAR_LST_TRIGGER
BEFORE INSERT
ON UC_JAR_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_JAR_LST_SEQ.nextval INTO :NEW.ID FROM dual;
-- Change the delimiter back to ';'
-- @DELIMITER ;
END;
-- Change the delimiter to '$'
-- @DELIMITER $
CREATE OR REPLACE TRIGGER UC_UPD_LST_TRIGGER
BEFORE INSERT
ON UC_UPD_LST
REFERENCING NEW AS NEW
FOR EACH ROW
BEGIN
SELECT UC_UPD_LST_SEQ.nextval INTO :NEW.ID FROM dual;
-- Change the delimiter back to ';'
-- @DELIMITER ;
END;
并且执行结束,没有错误。
【讨论】:
以上是关于iBatis 的 ScriptRunner 无法执行完全有效的 SQL 脚本的主要内容,如果未能解决你的问题,请参考以下文章
Oracle某条资料被锁如何解锁 (ScriptRunner,v$locked_object,SID和SERIAL#)