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
相关产品推荐
相关产品推荐

