You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cypress 10连接Oracle数据库失败:ORA-12154错误求助

在Cypress 10中解决Oracle数据库ORA-12154连接错误的方案

核心问题:连接字符串格式不兼容

你当前的connectString使用了JDBC风格的格式:

"jdbc:oracle:thin:@<hostname>:<port>:<sid>"

但node-oracledb并不支持这种JDBC格式的连接串,这是触发ORA-12154错误的直接原因,需要替换为Oracle原生的连接格式。

可选的正确连接格式

  • 简易格式(SID):直接使用主机、端口、SID组合,用冒号分隔
    "<hostname>:<port>:<sid>"
    
  • 简易格式(服务名):如果用服务名而非SID,使用斜杠分隔
    "<hostname>:<port>/<service_name>"
    
  • TNS别名格式:如果tnsnames.ora已配置好别名,直接填写别名即可,但需要确保node-oracledb能找到该文件(可通过设置TNS_ADMIN环境变量指向tnsnames.ora所在目录,或把文件放到Instant Client的network/admin目录下)

代码调整步骤

1. 修正连接配置

将db_config中的connectString改为node-oracledb支持的格式:

const db_config = {
  user: "<username>",
  password: "<password>",
  connectString: "<hostname>:<port>:<sid>" // 去掉JDBC前缀,保留原生格式
};

2. 优化异步任务的错误与连接管理

当前代码存在两个小问题:

  • conn.close()是异步操作,未加await可能导致连接泄漏
  • 测试代码直接访问rows属性,若连接失败会触发报错

调整后的queryData函数:

const queryData = async(query: string, dbconfig: any) => {
  let conn;
  try{
    conn = await oracledb.getConnection(dbconfig);
    console.log("NOTE===>connect established");
    const result = await conn.execute(query);
    return { success: true, rows: result.rows }; // 统一返回成功格式
  }catch(err: any){
    console.log("Error===>"+err.message);
    return { success: false, error: err.message }; // 统一返回错误格式
  } finally{
    if(conn){
      try{
        await conn.close(); // 添加await确保连接关闭完成
      }catch(err: any){
        console.log("Error===>"+err.message);
      }
    }
  }
}

对应的测试代码调整:

Then("I do a test database call", () => {
  const query = "SELECT id FROM table_name FETCH NEXT 1 ROWS ONLY"
  cy.task("sqlQuery", query).then((result: any) => {
    if (!result.success) {
      throw new Error(`数据库查询失败:${result.error}`);
    }
    result.rows.forEach((item: any) => {
      console.log("result==>" + item);
    });
  })
})

3. 确认Instant Client兼容性

你使用的oracledb@5.4.0搭配Instant Client 21_6是兼容的,但要确保是对应系统的版本(比如Windows 64位),且路径配置正确(你已确认路径无误,这一步可跳过)。


调整后的完整cypress.config.ts示例

import { defineConfig } from "cypress";
import createBundler from "@bahmutov/cypress-esbuild-preprocessor";
import { addCucumberPreprocessorPlugin } from "@badeball/cypress-cucumber-preprocessor";
import createEsbuildPlugin from "@badeball/cypress-cucumber-preprocessor/esbuild";
const oracledb = require("oracledb");

oracledb.initOracleClient({ libDir: "C:\\Users\\davethepunkyone\\instantclient_21_6" });

// 修正后的数据库配置
const db_config = {
  user: "<username>",
  password: "<password>",
  connectString: "<hostname>:<port>:<sid>"
};

const queryData = async(query: string, dbconfig: any) => {
  let conn;
  try{
    conn = await oracledb.getConnection(dbconfig);
    console.log("NOTE===>connect established");
    const result = await conn.execute(query);
    return { success: true, rows: result.rows };
  }catch(err: any){
    console.log("Error===>"+err.message);
    return { success: false, error: err.message };
  } finally{
    if(conn){
      try{
        await conn.close();
      }catch(err: any){
        console.log("Error===>"+err.message);
      }
    }
  }
}

async function setupNodeEvents(
  on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions ): Promise<Cypress.PluginConfigOptions> {
    await addCucumberPreprocessorPlugin(on, config);

    on("file:preprocessor", createBundler({
        plugins: [createEsbuildPlugin(config)],
      })
    );

    on("task", {
      sqlQuery: (query: string) => {
        return queryData(query, db_config);
      },
    });

    return config;
}

export default defineConfig({
  e2e: {
    specPattern: "**/*.feature",
    supportFile: false,
    setupNodeEvents,
  },
});

额外检查项

  • 确认远程Oracle数据库的端口、SID/服务名与Selenium项目中使用的完全一致
  • 若使用TNS别名,需设置TNS_ADMIN环境变量指向tnsnames.ora所在目录(Windows可在系统环境变量中添加,或启动Cypress前执行set TNS_ADMIN=C:\path\to\tns\directory)
  • 验证本地防火墙未阻挡Oracle数据库的端口连接

内容的提问来源于stack exchange,提问作者Dave H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 00:36:21