java - Spring Boot schema.sql,使用PL/SQL初始化数据库

标签 java oracle spring-boot plsql oracle12c

我正在开发一个必须使用 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 不知道它应该在“开始”和“结束”之间运行语句。 知道如何解决数据库初始化问题吗?

作为一种解决方法,我可以在每个应用程序运行时删除表,但这不是最佳解决方案(并且当有人第一次运行该应用程序时它不会工作)。

最佳答案

首先,我想分享两个似乎与这个问题相关的主题:

在那里您将找到一个可行的解决方案:创建一个存储过程并在您的schema.sql语句中使用,例如

call recreate_table('USER_DATA','CREATE TABLE USER_DATA (SOME DATA)');  

CALL语句广泛应用于不同的数据库,简化为只有一个分号的语句,效果很好。

其次,我可能只是假设,主要问题是 PL/SQL 中的匿名 block (以及其他可能包含多个分号的足够复杂的语句)应该由/ 字符。我建议您尝试将此字符附加到脚本末尾,看看 thisthis答案,如果不起作用,请创建一个存储过程。

另请注意,还有另一种方法可以检查表是否存在(通过此等待异常模式):

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/

相关文章:

oracle - rfc2047 电子邮件主题中的多个编码字

.net - 最佳实践 : . NET : How to return PK against an oracle database?

spring - Kotlin application.yml 数据类寻找 beans

java - Eclipse插件: get extended class name using ASTParser

Java 8 Instant.range 和 Instant.with 出现不一致

java - JDBC ResultSet 获取具有表别名的列

java - Jackson 将对象序列化为字符串

java - Jhipster CORS 启用

java - 有助于在 Android 中进行代码检查的工具

Java:通过使用最终 setter 避免警告 "Overridable method call in constructor"