我正在开发一个必须使用 Oracle Database 12c 的项目,并且必须手动编写所有查询(因此我无法使用 Spring Data)。 为了创建所有表和关系,我使用 schema.sql,对于模板数据,我使用 data.sql。
我在检查表或数据是否已存在时遇到问题。 在 MySQL 中创建表就像“如果不存在则创建表”。 不幸的是,在 PL/SQL 中,没有“if not存在”的对应词。我将此功能替换为:
begin
execute immediate
'CREATE TABLE user_data (
some data
)';
exception when others then if SQLCODE = -955 then null; else raise; end if;
end;
当我在 SQL Developer 或 Intellij 的 SQL 控制台中运行此脚本时,它可以工作,但当我想运行应用程序并且 Spring Boot 尝试从 schema.sql 执行脚本时,就会出现问题。
终端中的输出表明:
nested exception is java.sql.SQLException: ORA-06550: line 8, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem return
returning <an exponent (**)> <> or != or ~= >= <= <> and or
like like2 like4 likec between into using || multiset bulk
member submultiset
所以看起来 Spring Boot 不知道它应该在“开始”和“结束”之间运行语句。 知道如何解决数据库初始化问题吗?
作为一种解决方法,我可以在每个应用程序运行时删除表,但这不是最佳解决方案(并且当有人第一次运行该应用程序时它不会工作)。
最佳答案
首先,我想分享两个似乎与这个问题相关的主题:
- Unable to use "DROP TABLE IF EXISTS" in schema.sql for a Spring Boot application
- executeSqlScript fails with Spring for PL/SQL block
在那里您将找到一个可行的解决方案:创建一个存储过程并在您的schema.sql
语句中使用,例如
call recreate_table('USER_DATA','CREATE TABLE USER_DATA (SOME DATA)');
CALL
语句广泛应用于不同的数据库,简化为只有一个分号的语句,效果很好。
其次,我可能只是假设,主要问题是 PL/SQL 中的匿名 block (以及其他可能包含多个分号的足够复杂的语句)应该由/
字符。我建议您尝试将此字符附加到脚本末尾,看看 this和 this答案,如果不起作用,请创建一个存储过程。
另请注意,还有另一种方法可以检查表是否存在(通过此等待异常模式):
select count(*)
from user_tables t
where t.table_name = 'USER_DATA'
and rownum < 2
关于java - Spring Boot schema.sql,使用PL/SQL初始化数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48023461/