Oracle测试容器引发SQLSyntaxErrorException:ORA-01918:用户不存在

cnjp1d6j  于 2023-10-16  发布在  Oracle
关注(0)|答案(1)|浏览(114)

我是Oracle容器的新手,我有一个测试容器来打开2个数据库连接,因为我的Spring Boot 应用程序中有2个数据库。
这是我创建Oracle容器示例的抽象类:

@Slf4j
public class AbstractContanierBaseTest {

    static final OracleContainer ORACLE_OPIOWNER_CONTANINER;
    static final OracleContainer ORACLE_FIRMAOWNER_CONTANINER;

    static {
        ORACLE_OPIOWNER_CONTANINER = new OracleContainer("gvenzl/oracle-xe:21-slim");
        ORACLE_OPIOWNER_CONTANINER
                .withUsername("opiowner")
                .withPassword("password")
                .withDatabaseName("OPIOWNER")
                .withExposedPorts(1521)
                .withLogConsumer(new Slf4jLogConsumer(log))
                .withEnv("ORACLE_DATABASE", "OPIOWNER")
                .withEnv("ORACLE_PASSWORD", "password")
                .withEnv("APP_USER", "opiowner")
                .withEnv("APP_USER_PASSWORD", "password")
                .usingSid();
        ORACLE_OPIOWNER_CONTANINER.start();

        System.setProperty("spring.datasource.driver-class-name", ORACLE_OPIOWNER_CONTANINER.getDriverClassName());
        System.setProperty("spring.datasource.url", ORACLE_OPIOWNER_CONTANINER.getJdbcUrl());
        System.setProperty("spring.datasource.username", ORACLE_OPIOWNER_CONTANINER.getUsername());
        System.setProperty("spring.datasource.password", ORACLE_OPIOWNER_CONTANINER.getPassword());

        ORACLE_FIRMAOWNER_CONTANINER = new OracleContainer("gvenzl/oracle-xe:11-slim");
        ORACLE_FIRMAOWNER_CONTANINER
                .withUsername("firmaowner")
                .withPassword("password")
                .withDatabaseName("FIRMAOWNER")
                .withLogConsumer(new Slf4jLogConsumer(log))
                .withEnv("ORACLE_PASSWORD", "password")
                .withEnv("APP_USER", "firmaowner")
                .withEnv("APP_USER_PASSWORD", "password")
                .usingSid();
        ;
        ORACLE_FIRMAOWNER_CONTANINER.start();

        System.setProperty("spring.second-datasource.url", ORACLE_FIRMAOWNER_CONTANINER.getJdbcUrl());
        System.setProperty("spring.second-datasource.username", ORACLE_FIRMAOWNER_CONTANINER.getUsername());
        System.setProperty("spring.second-datasource.password", ORACLE_FIRMAOWNER_CONTANINER.getPassword());

    }

这个类继承了我在junit5中编写的集成测试。
当执行junits时,在测试之前通过@Sql注解启动SQL脚本:

@Sql(config = @SqlConfig(transactionManager = "opiownerTransactionManager"), scripts = {"classpath:scripts/ddl/Recall_create_table_opiConfluenzaDati.sql", "classpath:scripts/dml/Recall_opiConfluenzaDati_script.sql"})

脚本执行正常,但我收到一个oracle SqlSyntaxException作为每个问题的标题。
这是我的创建表脚本:

CREATE TABLE opiowner.OPI_CONFLUENZA_DATI
(
    "OPI_ANNO_EMISSIONE_TITOLO" NUMBER(4,0),
    "OPI_TIPOLOGIADISPOSIZIONE" VARCHAR2(11),
    "OPI_DATADISPOSIZIONE" DATE,
    "OPI_ID_DISPOSIZIONE" NUMBER(10,0) NOT NULL,
    "OPI_NUM_TITOLO" NUMBER(9,0),
    "OPI_PROG_QUOTA" NUMBER(15,0),
    "OPI_TIPO_COD_BENEF" VARCHAR2(2),
    "OPI_CODICE_BENEF" VARCHAR2(16),
    "OPI_TIPO_RECORD" VARCHAR2(11),
    "OPI_SPECIE_TITOLO" VARCHAR2(2),
    "OPI_TIPO_SPESA" VARCHAR2(5),
    "OPI_COD_ENTE" VARCHAR2(15),
    "OPI_IMPORTO" NUMBER(15,3),
    "OPI_NOME_FILE" VARCHAR2(100),
    "OPI_ORDINANTE" VARCHAR2(100)
);

ALTER TABLE opiowner.OPI_CONFLUENZA_DATI
ADD CONSTRAINT OPI_CONFLUENZA_DATI_PK PRIMARY KEY ("OPI_TIPOLOGIADISPOSIZIONE", "OPI_DATADISPOSIZIONE", "OPI_ID_DISPOSIZIONE");

正如你可能猜到的,我需要“opiowner”用户存在于数据库中。特别是在Oracle容器的第一个示例中:ORACLE_OPIOWNER首先。

**问题:**如何在Oracle Container示例中创建“opiowner”用户?

我认为方法withUsernamewithPassword可以做到这一点,但它们不.
因此,正如你可以看到的,使用方法withEnv,我试图覆盖Docker镜像的环境变量,但仍然没有办法。
如何解决这个问题?

9rbhqvlz

9rbhqvlz1#

我想我找到了你面临的问题。请通过下面的Github问题
[OracleContainer] Unable to execute statements which need system privileges

**注意:**我不是DBMaven。

根据上面提供的信息,我的答案如下:

  • 对于oracle-xe映像,现在默认用户和模式为“TEST"。
  • 我猜你将无法创建任何随机用户,你没有特权。为了克服这个问题,你必须使用TESTuser,它是测试容器的超级用户(Oracle Test containers使用/detectsTEST作为默认用户)。
  • 所以,我可以建议创建一个init.sql,如下所示:
CREATE USER OPIOWNER IDENTIFIED BY password;
GRANT CONNECT TO OPIOWNER;
GRANT SYSDBA TO OPIOWNER;
GRANT CREATE SESSION GRANT ANY PRIVILEGE TO OPIOWNER;
GRANT UNLIMITED TABLESPACE TO OPIOWNER;
  • AbstractContanierBaseTest类更新为如下所示:
@Slf4
  public class AbstractContanierBaseTest {

  static final OracleContainer ORACLE_OPIOWNER_CONTANINER;
  static final OracleContainer ORACLE_FIRMAOWNER_CONTANINER;

  static {
      ORACLE_OPIOWNER_CONTANINER = new OracleContainer("gvenzl/oracle-xe:21-slim");
      ORACLE_OPIOWNER_CONTANINER
              .withUsername("test")
              .withInitScript("init.sql");
              .usingSid();
      ORACLE_OPIOWNER_CONTANINER.start();

      System.setProperty("spring.datasource.driver-class-name", ORACLE_OPIOWNER_CONTANINER.getDriverClassName());
      System.setProperty("spring.datasource.url", ORACLE_OPIOWNER_CONTANINER.getJdbcUrl());
      System.setProperty("spring.datasource.username", ORACLE_OPIOWNER_CONTANINER.getUsername());
      System.setProperty("spring.datasource.password", ORACLE_OPIOWNER_CONTANINER.getPassword());

      ORACLE_FIRMAOWNER_CONTANINER = new OracleContainer("gvenzl/oracle-xe:11-slim").withCopyFileToContainer(MountableFile.forClasspathResource("init.sql"), "/container-entrypoint-startdb.d/init.sql");
      ORACLE_FIRMAOWNER_CONTANINER
              .withUsername("firmaowner")
              .withPassword("password")
              .withDatabaseName("FIRMAOWNER")
              .withLogConsumer(new Slf4jLogConsumer(log))
              .withEnv("ORACLE_PASSWORD", "password")
              .withEnv("APP_USER", "firmaowner")
              .withEnv("APP_USER_PASSWORD", "password")
              .usingSid();
      ;
      ORACLE_FIRMAOWNER_CONTANINER.start();

      System.setProperty("spring.second-datasource.url", ORACLE_FIRMAOWNER_CONTANINER.getJdbcUrl());
      System.setProperty("spring.second-datasource.username", ORACLE_FIRMAOWNER_CONTANINER.getUsername());
      System.setProperty("spring.second-datasource.password", ORACLE_FIRMAOWNER_CONTANINER.getPassword());

  }
  • 现在,将create table脚本更新为:
ALTER SESSION SET CONTAINER=<<NAME OF TEST CONTAINER>>;

  CREATE TABLE TEST.OPI_CONFLUENZA_DATI
  (
      "OPI_ANNO_EMISSIONE_TITOLO" NUMBER(4,0),
      "OPI_TIPOLOGIADISPOSIZIONE" VARCHAR2(11),
      "OPI_DATADISPOSIZIONE" DATE,
      "OPI_ID_DISPOSIZIONE" NUMBER(10,0) NOT NULL,
      "OPI_NUM_TITOLO" NUMBER(9,0),
      "OPI_PROG_QUOTA" NUMBER(15,0),
      "OPI_TIPO_COD_BENEF" VARCHAR2(2),
      "OPI_CODICE_BENEF" VARCHAR2(16),
      "OPI_TIPO_RECORD" VARCHAR2(11),
      "OPI_SPECIE_TITOLO" VARCHAR2(2),
      "OPI_TIPO_SPESA" VARCHAR2(5),
      "OPI_COD_ENTE" VARCHAR2(15),
      "OPI_IMPORTO" NUMBER(15,3),
      "OPI_NOME_FILE" VARCHAR2(100),
      "OPI_ORDINANTE" VARCHAR2(100)
   );

   ALTER TABLE TEST.OPI_CONFLUENZA_DATI
   ADD CONSTRAINT OPI_CONFLUENZA_DATI_PK PRIMARY KEY ("OPI_TIPOLOGIADISPOSIZIONE", "OPI_DATADISPOSIZIONE", "OPI_ID_DISPOSIZIONE");

看看这个变化是否有效。仅此而已查看github issue以获取更多信息。

相关问题