BeanShell Sampler执行Oracle数据库循环插入记录时抛出500错误
解决BeanShell Sampler执行Oracle循环插入报错的问题
Hey there, let's break down what's going wrong here and fix it step by step:
核心错误原因
你遇到的org.apache.commons.dbcp2.DelegatingStatement找不到setString()方法的报错,本质是你在Statement对象上调用了只属于PreparedStatement的方法。Statement是用来执行静态无参数SQL的,根本没有参数绑定相关的方法,这是脚本里最关键的逻辑错误。
脚本里的其他问题
除了上面的核心错误,你的脚本还有几个混乱点:
- 你先创建了
PreparedStatement pstmt但完全没用到,反而新建了Statement stmt执行逻辑,属于冗余代码; - 你的PL/SQL匿名块没有定义任何输入/输出参数,却调用了
registerOutParameter(),这完全没必要; - 原始PL/SQL块存在语法小错误(变量声明缺分号、插入语句末尾缺分号、字段名拼写错误
OCATION_NO),这些在SQL Developer里可能被自动修正,但JDBC执行时会触发语法异常。
修正后的完整脚本
下面是修复后的BeanShell脚本,已经解决了所有问题:
import java.sql.*; import oracle.jdbc.*; import org.apache.jmeter.protocol.jdbc.config.DataSourceElement; Connection conn = null; Statement stmt = null; try { // 从JMeter数据源获取连接 conn = DataSourceElement.getConnection("IMPACTConnectionPrerequisitsII"); // 修正语法错误后的PL/SQL循环插入块 String query = "DECLARE " + "j number(4); " + "BEGIN " + "FOR j in 11 .. 12 LOOP " + "INSERT INTO FWA_STAGE_TU " + "(ID,EXT_ID,BATCH_NO,OPERATION,BLOCK_ROLL_UP_LAST_RECORD,LAST_UPDATED_DATE,ERROR_FLAG,TRIAL_NO,TRIAL_ALIAS_CODE, " + "COUNTRY_CODE,DISPLAY_UNIT_NO,GROUP_NO,TRIAL_UNIT_REFERENCE,PRIMARY_INVESTIGATOR,PRIMARY_CENTRE,LOCATION_NO, " + "PURPOSE_CODE,MANAGING_MED_UNIT_CODE,UPDATING_MED_UNIT_CODE,FINANCE_MED_UNIT_CODE,PATIENTS_ALL_SET_UP_FLAG, " + "PATIENT_MONITORING_FLAG,COMMENTS,CONFIRMED_FLAG,CONFIRMED_BY,CONFIRMED_DATE,ROLLUP_ROLLDOWN_PLANNED_FIGS, " + "DOC_COLLECTION_INDICATOR,VALIDATED_PAT_CAP,MAXIMUM_PAT_CAP,PREFERRED_LANGUAGE_CODE,NEW_DISPLAY_UNIT_NO, " + "TOTAL_OPEN_DCF_ISSUES_NO,ORDER_INTERVAL,ORDER_INTERVAL_UNITS,DATA_SOURCE_CODE,RANK_SEQ) " + "VALUES (j, 1, 10, 'I', NULL, SYSDATE, 'N', 102922, 'TESTTRIAL4', 'BEL', " + "j, NULL, 'BELTU'||j, 130262, 124236, NULL, 'PATTR', 'FP', 'FP', 'FP', 'N', 'Y', 'TESTTU'||j, " + "'Y', 999999, SYSDATE, NULL, 'P', 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL); " + "END LOOP; " + "END;"; // 创建Statement执行静态PL/SQL块 stmt = conn.createStatement(); stmt.execute(query); log.info("循环插入操作执行成功!"); } catch(Throwable ex) { log.error("执行插入失败: ", ex); throw ex; } finally { // 按顺序关闭资源,每个关闭操作单独加try-catch避免掩盖原始错误 if (stmt != null) { try { stmt.close(); } catch (SQLException e) { log.error("关闭Statement失败: ", e); } } if (conn != null) { try { conn.close(); log.info("数据库连接已成功关闭!"); } catch (SQLException e) { log.error("关闭数据库连接失败: ", e); } } }
额外提示
- 如果之后需要执行带参数的SQL,一定要用
PreparedStatement,并通过它的setXxx()方法绑定参数,而不是用Statement; - 资源关闭的顺序要遵循
ResultSet -> Statement -> Connection,避免出现资源泄漏; - 执行PL/SQL块时,确保语法完全正确,尤其是分号的位置,JDBC对PL/SQL的语法要求比SQL Developer更严格。
内容的提问来源于stack exchange,提问作者user16923013
相关产品推荐
相关产品推荐

