我正在测试一个将数据读/写到Oracle DB的Spring Boot应用程序。该Oracle DB具有Oracle软件包以及这些软件包中的过程。在某个时候,spring boot应用程序通过实体存储库调用此过程,如下所示:
@Repository
public interface StudentRepository extends JpaRepository<Student, String> {
@Modifying
@Query(value = "begin sch1.STUDENT_PACKAGE.Set_Grades_To_A('A'); end;", nativeQuery = true)
public void setStudentGradeToA();
}
因此,它使用本机查询来调用Set_GradesToA
模式的STUDENT_PACKAGE
包中的过程sch1
。
我目前正在测试Spring Boot应用程序的功能,并且否它与Oracle数据库之间的集成。因此,我决定暂时使用内存数据库(H2)(带有Oracle兼容性选项)替换Oracle DB。 但是我该如何伪造这些Java打包过程?
我尝试如下在schema.sql(或data.sql)中创建别名:
CREATE SCHEMA if not exists sch1;
CREATE ALIAS sch1.STUDENT_PACKAGE AS $$ void Set_Grades_To_A(String s) { new String(s); } $$;
我真的不在乎Set_Grades_To_A
过程中的内容,我关心的是如何定义它。
如上所述创建别名时,仍然出现语法错误。
Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "BEGIN SCH1[*].STUDENT_PACKAGE.Set_Grades_To_A('A'); END; "; SQL statement:
begin sch1.STUDENT_PACKAGE.Set_Grades_To_A('A'); end; [42000-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.message.DbException.getSyntaxError(DbException.java:203)
我想我有两个问题:
如何伪造sch1模式中Oracle软件包内部的存储过程?
为什么会出现上述语法错误?
答案 0 :(得分:0)
这就是我所做的。
问题2:要回答此问题,我必须按以下方式更改本机查询
class FileManager : public QAbstractListModel
{
Q_OBJECT
public:
explicit FileManager(QObject *parent = nullptr);
enum RoleNames {
INDEX = Qt::UserRole + 1,
PATH,
TYPE,
CATEGORY
};
/**
* @brief Opens a file
* @param filePath The path to the file
* @return false if the opening fails, true otherwise
* Opens a file, and if successful, returns true and adds it to this model. Otherwise, it returns false.
*/
Q_INVOKABLE
bool openFile(QUrl filePath);
Q_INVOKABLE
GenericFile* getFile(int index) {
if (index >= 0 && index < files.length()) {
return files[index];
}
return nullptr;
}
Q_INVOKABLE
ArchiveFile* getArchive(int index) {
qDebug() << "Callled getArchive";
try {
return dynamic_cast<ArchiveFile*>(getFile(index));
} catch (std::bad_cast e){
return nullptr;
}
}
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
private:
QList<GenericFile*> files;
};
问题1:涉及到三件事。现在,我已经如上所述更改了本机查询,我得到了另一个错误:
@Repository
public interface StudentRepository extends JpaRepository<Student, String> {
@Modifying
@Query(value = "call sch1.STUDENT_PACKAGE.Set_Grades_To_A('A')", nativeQuery = true)
public void setStudentGradeToA();
}
它正在寻找一个名为Caused by: org.h2.jdbc.JdbcSQLException: Database "sch1" not found; SQL statement:
call sch1.STUDENT_PACKAGE.Set_Grades_To_A('A') [90013-197]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
的数据库。似乎在H2中用于调用存储过程的模式是sch1
。由于我不在乎该过程实际上是什么,因此我可以通过创建一个名为database.schema.procedure_name
的数据库,一个名为sch1
的模式和过程名称为STUDENT_PACKAGE
要创建内存数据库,必须在Set_Grades_To_A
文件中设置以下属性spring.datasource.url
。
application.properties
的方式创建sch1
数据库。请注意,数据库名称为spring.datasource.url=jdbc:h2:mem:sch1;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=CREATE SCHEMA IF NOT EXISTS first_schema
sch1
添加到STUDENT_PACKAGE
的末尾来创建\\;CREATE SCHEMA IF NOT EXISTS STUDENT_PACKAGE
模式。这将添加另一个名为spring.datasource.url
的架构。该属性应如下所示:STUDENT_PACKAGE
spring.datasource.url=jdbc:h2:mem:sch1;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;MODE=Oracle;INIT=CREATE SCHEMA IF NOT EXISTS first_schema\\;CREATE SCHEMA IF NOT EXISTS STUDENT_PACKAGE
存储过程添加到schema.sql Set_Grades_To_A
答案 1 :(得分:0)
我能够通过添加IGNORE_CATALOGS=TRUE
spring.datasource.url = jdbc:h2:mem:testdb;MODE=Oracle;IGNORE_CATALOGS=TRUE
这将忽略数据库名称