- 前言~
- 1.准备事项
- 1.1 梳理脚本
- 2.动起手来
- 2.1 了解 JDBC Connection Configuration
- 2.2 配置 JDBC请求
- 3.生成测试链路
- 3.1 获取表主键信息
- 3.2 获取目标表表结构
- 3.3 拼接数据并生成sql
- 3.4 插入数据
- 4.优化脚本(主键信息
- 4.1 添加Beshell后置处理器
- 4.2 优化拼接数据请求(1)
- 4.3 新增序列信息
- 4.4 优化拼接数据请求(2)
- 5.批量插入数据
- 5.1 插入数据编写
- 5.总结
前言~
引言:由于工作需要,我需要向Oracle数据库批量插入一批数据,那么手动一条一条插入肯定不行的,所以就想到了使用Jmter来插入数据,这样方便又省事还更高效,当然用其他方式也可以,这里只是记录一下我自己的思路
1.准备事项
1.1 梳理脚本
编写脚本首先需要梳理我应该做什么
1.目标数据库的连接信息(服务器ip、账号、密码、端口、服务名、写入模式等
2.指定的数据库表(这里可以帮助获取表的结构及字段
3.指定表是否存在主键等因素(因为插入数据的时候批量插入会报错唯一值错误,下面会列举
4.插入数据
============================================================================
将我们需要做的步骤梳理出来那么就清晰很多了,拿我自己的数据库举例
1.数据库连接信息
jdbc:oracle:thin:@192.168.3.203:1522/rac?allowMultiQueries=true
2.指定的数据库表(当然你随机获取也行
模式:TEST
表:MK_SV_ET_DATA_LIST
3.获取指定表是否存在主键
## 这里使用的是子查询,首先需要获取到【唯一键的信息】,然后通过唯一键信息查找属于这个表的主键列信息
SELECT column_name
FROM all_cons_columns
WHERE constraint_name = (
SELECT constraint_name
FROM all_constraints
WHERE constraint_type = 'P'
AND OWNER='${database_name}' AND TABLE_NAME='${table_name}'
)
## OWNER : 就是你的模式名
## TABLE_NAME : 指的是你需要获取的表
## constraint_type : 指的是主键
4.插入数据
## 这里一开始考虑的场景是没有主键的情况。
## 只是批量插入一组又一组的数据
## 这个模板不需要改动,因为他只是被动接收数据的一个请求
BEGIN
FOR I IN 1..10000
LOOP
${sql};
IF MOD(I,1000)=0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;
以上就是我们需要达到的目的了,往下看道阻且长~
2.动起手来
2.1 了解 JDBC Connection Configuration
- JDBC Connection Configuration 算是一个数据库连接池配置
- Variable Name :数据库连接池的名称
- 一个测试计划可以有多个 JDBC Connection,只要名称不重复就行
1.从配置原件中选择JDBC Connection Configuration
2.JDBC Connection Configuration介绍
- Connection pool Configuration
字段 | 含义 |
---|---|
Max Number of Connections | 最大连接数;做性能测试时,建议填 0如果填了10,则最大连接10个线程 |
Max Wait(ms) | 在连接池中取回连接最大等待时间,单位毫秒 |
Time Between Eviction Runs(ms) | 线程可空闲时间,单位毫秒 。如果当前连接池中某个连接在空闲了 time BetweenEviction Runs Millis 时间后任然没有使用,则被物理性的关闭掉 |
Auto Commit | 自动提交sql语句,如:修改数据库时,自动 commit |
Transaction isolation | 事务隔离级别 |
Preinit Pool | 立即初始化连接池 如果为 False,则第一个 JDBC 请求的响应时间会较长,因为包含了连接池建立的时间 |
- Connection Validation by Pool
字段 | 含义 |
---|---|
Test While Idle | 当连接空闲时是否断开 |
Soft Min Evictable Idle Time(ms) | 连接在池中处于空闲状态的最短时间 |
Validation Query | 一个简单的查询,用于确定数据库是否仍在响应 默认为jdbc驱动程序的 isValid() 方法,适用于许多数据库 |
- Database Connection Configuration 数据库连接配置
字段 | 含义 |
---|---|
Database URL | 数据库连接 URL |
JDBC Driver class | 数据库驱动 |
Username | 数据库登录用户名 |
Password | 数据库登录密码 |
Connection Properties | 建立连接时要设置的连接属性 |
我的配置:
Variable Name:oracl
Database URL:jdbc:oracle:thin:@192.168.3.203:1522/rac?allowMultiQueries=true
JDBC Driver class:oracle.jdbc.Oracledriver
Username:NOAH
Password:test111
常见数据库的连接 URL和驱动
数据库 | 驱动 | URL |
---|---|---|
MySQL | com.mysql.jdbc.Driver | jdbc:mysql://host:port/{dbname} |
PostgreSQL | org.postgresql.Driver | jdbc:postgresql:{dbname} |
Oracle | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:user/pass@//host:port/service |
sqlServer | com.microsoft.sqlserver.jdbc.SQLServerDriver | jdbc:sqlserver://host:port;databaseName=databaseName |
2.2 配置 JDBC请求
- 字段介绍
字段 | 含义 |
---|---|
Variable Name Bound to Pool | 数据库连接池配置的名称 |
Query Type | sql 语句的类型 |
SQL Query | sql 语句 语句结尾不需要添加 ; 变量用 ? 占位 |
Parameter values | 需要传递的变量值,多个变量用 , 分隔 |
Parameter types | 变量类型 |
Variable Names | 保存sql语句返回的数据和返回数据的总行数用 , 分隔 跳过列用空 |
Result Variable Name | 一个 Object 变量存储所有返回值 |
Query timeout(s) | 超时时间;默认0,代表无限时间 |
Limit ResultSet | 和 limit 类似作用,限制 sql 语句返回结果集的行数 |
Handle ResultSet | 如何定义 callable statements 返回的结果集;默认是存储为字符串 |
安装上面介绍的步骤填写就行了
- 需要找一张有数据的表哈。指定模式下的表也行
这里以这张表为例子
配置连接信息
运行脚本查看是否有结果
与我们查出来的是一致的
- 参数化设置
这里设置的是查询五条数据
不过需要注意的是,需要注意传入数据的类型,如果不符合的话会报错
3.生成测试链路
3.1 获取表主键信息
上面已经介绍过jdbc是如何处理操作了。现在我们需要做的就是将我们的步骤串联起来
- 建表语句
CREATE TABLE "NOAH"."MK_SV_ET_DATA_LIST"
( "ELEC_DATA_LIST_ID" VARCHAR2(128) NOT NULL ENABLE,
"WO_NO" VARCHAR2(128) NOT NULL ENABLE,
"TASK_NO" VARCHAR2(128),
"DATA_NAME" VARCHAR2(128),
"CREATE_TIME" DATE NOT NULL ENABLE,
"OPERATED_TIME" DATE NOT NULL ENABLE,
"ELEC_CUST_NO" VARCHAR2(128),
"EFFECT_DATE" DATE,
"DUE_DATE" DATE,
"DATA_STATUS_CODE" VARCHAR2(128),
"DATA_TYPE_CODE" VARCHAR2(128),
"DATA_NO" VARCHAR2(128),
"SUPPLY_ORG_NO" VARCHAR2(128),
"AREA_CODE" VARCHAR2(128),
"REMARKS" VARCHAR2(256),
"VERI_TIME" DATE,
"VERI_EMP_ID" VARCHAR2(128),
"DATA_BIG_SORT_CODE" VARCHAR2(128)
);
alter table NOAH.MK_SV_ET_DATA_LIST add constraint PK_FW_YKDZHZLQD primary key (ELEC_DATA_LIST_ID, WO_NO);
这里使用简单的sql查询就行了,我这张表是存在两个主键的
1. 查询表主键
2. 查询主键结果
到这里我们就可以将目标表的主键信息取到了,问题是我们如何使用这取到的数据呢? 先不着急,先把后面的步骤走完再说
3.2 获取目标表表结构
接下来到了获取表结构的时候了,我们可以通过all_tables表来获取表的结构信息
SELECT
column_name,
data_type
FROM
all_tab_columns
WHERE
owner = 'NOAH'
AND table_name = 'MK_SV_ET_DATA_LIST'
1.创建获取表结构的jdbc请求
2.查询结果
到了这里我们的任务完成到了2/4 ,还差最后最关键的两步了。那么如果通过jmeter将以上的信息拼接到一起?
3.3 拼接数据并生成sql
首先我们要知道,在jmeter中没有直接提供给我们拼接的请求,所以需要我们自己处理数据,所以这里笔者使用的是Beshell脚本,当然你们有更好的方法也可以使用
- 1.新增Beshell 取样器
- 2.处理数据
import java.util.ArrayList;
import java.util.List;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class SqlGenerator {
// 传入两个列表,一个是字段名称,一个是字段类型
public static String generateSql(List field_name_list, List field_type_list) {
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO NOAH.MK_SV_ET_DATA_LIST ("); // 将数据拼接到一个字符串中
// 先处理字段名称
for (int i = 0; i < field_name_list.size(); i++) {
sb.append(field_name_list.get(i));
if (i != field_name_list.size() - 1) {
sb.append(", ");
}
}
// 结构为INSERT INTO NOAH.MK_SV_ET_DATA_LIST ( c1,c2,c3..),
sb.append(") VALUES (");
// 根据字段类型添加对应的值,可以不用这么多值判断,看自己需要
for (int i = 0; i < field_type_list.size(); i++) {
String type = field_type_list.get(i);
if (type.equalsIgnoreCase("ROWID")) {
sb.append("NULL");
} else if (type.equalsIgnoreCase("INT") || type.equalsIgnoreCase("INTEGER") || type.equalsIgnoreCase("SMALLINT") || type.equalsIgnoreCase("TINYINT") || type.equalsIgnoreCase("BIGINT")) {
sb.append("${__Random(1,1000000,rang_int)}");
} else if (type.equalsIgnoreCase("NUMBER") || type.equalsIgnoreCase("DEC") || type.equalsIgnoreCase("DECIMAL") || type.equalsIgnoreCase("NUMERIC")) {
sb.append("${__Random(1,9,)}.${__Random(0,100,)}");
} else if (type.equalsIgnoreCase("FLOAT") || type.equalsIgnoreCase("REAL") || type.equalsIgnoreCase("DOUBLE") || type.equalsIgnoreCase("DOUBLE PRECISION")) {
sb.append("${__Random(1,8,)}.${__Random(0,100,)}");
} else if (type.equalsIgnoreCase("BINARY_FLOAT")) {
sb.append("${__Random(1,7,)}.${__Random(0,10000,)}");
} else if (type.equalsIgnoreCase("BINARY_DOUBLE")) {
sb.append("${__Random(1,10000000,)}.${__Random(0,100,)}");
} else if (type.equalsIgnoreCase("CHAR") || type.equalsIgnoreCase("CHARACTER") || type.equalsIgnoreCase("NCHAR") || type.equalsIgnoreCase("NVARCHAR2")
|| type.equalsIgnoreCase("VARCHAR") || type.equalsIgnoreCase("VARCHAR2")) {
sb.append("'${__RandomString(10,abcdefghijklmnopqrstuvwxyz90,)}'");
} else if (type.equalsIgnoreCase("TIMESTAMP") || type.equalsIgnoreCase("TIMESTAMP WITH LOCAL TIME ZONE")) {
sb.append("TO_TIMESTAMP('${__time(yyyy-MM-dd HH:mm:ss,time)}.000000', 'yyyy-mm-dd hh24:mi:ss.ff')");
} else if (type.equalsIgnoreCase("TIMESTAMP(6)")) {
sb.append("TO_TIMESTAMP('${__time(yyyy-MM-dd HH:mm:ss,time)}.000000', 'yyyy-mm-dd hh24:mi:ss.ff')");
} else if (type.equalsIgnoreCase("TIMESTAMP(6) WITH TIME ZONE")) {
sb.append("TO_TIMESTAMP_TZ('${__time(yyyy-MM-dd hh:mm:ss,time)}.000000 +08:00', 'yyyy-mm-dd hh24:mi:ss.ff tzr')");
} else if (type.equalsIgnoreCase("DATE")|| type.equalsIgnoreCase("DATETIME WITH TIME ZONE")) {
sb.append("TO_DATE('${__RandomDate(,2022-04-23,2023-04-23,,)}', 'yyyy-mm-dd')");
} else if (type.equalsIgnoreCase("INTERVAL YEAR TO MONTH")) {
sb.append("INTERVAL '${__Random(1,12,)}-${__Random(1,12,)}' YEAR TO MONTH");
} else if (type.equalsIgnoreCase("INTERVAL YEAR")) {
sb.append("INTERVAL '${__Random(1,12,)}' YEAR");
} else if (type.equalsIgnoreCase("INTERVAL MONTH")) {
sb.append("INTERVAL '${__Random(1,59,)}' MONTH");
} else if (type.equalsIgnoreCase("INTERVAL DAY")) {
sb.append("INTERVAL '${__Random(1,31,)}' DAY");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO HOUR")) {
sb.append("INTERVAL '${__Random(1,28,)} ${__Random(1,12,)}:${__Random(1,59,)}:${__Random(1,59,)}' DAY TO HOUR");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO MINUTE")) {
sb.append("INTERVAL '${__Random(1,12,)} ${__Random(1,59,)}:${__Random(1,59,)}' DAY TO MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO SECOND")) {
sb.append("INTERVAL '${__Random(1,28,)} ${__Random(1,12,)}:${__Random(1,59,)}:${__Random(1,59,)}' DAY TO SECOND");
} else if (type.equalsIgnoreCase("INTERVAL HOUR")) {
sb.append("INTERVAL '${__Random(1,12,)}' HOUR");
} else if (type.equalsIgnoreCase("INTERVAL HOUR TO MINUTE")) {
sb.append("INTERVAL '${__Random(1,12,)}:${__Random(1,59,)}' HOUR TO MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL HOUR TO SECOND")) {
sb.append("INTERVAL '${__Random(1,12,)}:${__Random(1,59,)}:${__Random(1,59,)}' HOUR TO SECOND");
} else if (type.equalsIgnoreCase("INTERVAL MINUTE")) {
sb.append("INTERVAL '${__Random(1,59,)}' MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL MINUTE TO SECOND")) {
sb.append("INTERVAL '${__Random(1,12,)}:${__Random(1,59,)}' MINUTE TO SECOND");
} else if (type.equalsIgnoreCase("INTERVAL SECOND")) {
sb.append("INTERVAL '${__Random(1,59,)}' SECOND");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO SECOND(6)")) {
sb.append("INTERVAL '${__Random(1,31,)} 12:34:56.789' DAY TO SECOND(3)");
} else if (type.equalsIgnoreCase("INTERVAL DAY(2) TO HOUR")) {
sb.append("INTERVAL '${__Random(1,31,)} ${__Random(1,12,)}' DAY TO HOUR");
} else if (type.equalsIgnoreCase("INTERVAL DAY(2) TO MINUTE")) {
sb.append("INTERVAL '${__Random(1,31,)} ${__Random(1,23,)}:${__Random(1,59,)}' DAY TO MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL YEAR(2) TO MONTH")) {
sb.append("INTERVAL '0${__Random(1,9,)}-0${__Random(1,9,)}' YEAR TO MONTH");
} else if (type.equalsIgnoreCase("INTERVAL DAY(2) TO SECOND(6)")) {
sb.append("INTERVAL '+2 0${__Random(1,9,)}:${__Random(1,59,)}:${__Random(1,59,)}.250000' DAY(2) TO SECOND(6)");
} else if (type.equalsIgnoreCase("BLOB")) {
sb.append("empty_blob()");
} else if (type.equalsIgnoreCase("CLOB")) {
sb.append("'test clob ${__RandomString(9,ERTYuzvbndm12,)}'");
} else if (type.equalsIgnoreCase("RAW")) {
sb.append("'${hexString}'");
} else{
// 如果没有这个数据类型,则置空 ''
sb.append("''");
}
if (i != field_type_list.size() - 1) {
sb.append(", "); // 处理最后一位数据的逗号
}
}
sb.append(")");
return sb.toString(); // 返回一个字符串的类型出去
}
}
String Info = prev.getResponseDataAsString(); // 获取上一个请求的响应数据
String[] AAA = Info.split("\n"); // 分割响应数据
List field_name_list = new ArrayList();
List field_type_list = new ArrayList();
for (int i = 1; i < AAA.length; i++) {
String[] fields = AAA[i].split("\t");
String field_name = String.valueOf(fields[0]);
field_name_list.add(field_name); // 将值存入列表中
String field_type = String.valueOf(fields[1]);
field_type_list.add(field_type);
}
// 生成 SQL 语句
String sql = SqlGenerator.generateSql(field_name_list, field_type_list);
log.info("INSERT SQL ====>" + sql);
vars.put("sql", sql);
- 3.执行脚本
获取到的数据结果~~
OK 那么到这儿 我们离成功就只差一步了 兄弟们!!!继续往下走
3.4 插入数据
因为我们已经在上一个请求中获取到了生成的sql,并将它设置成了当前线程组中的变量,所以可以直接引用
果然不错所料的插入报错了,因为这里插入的是一个随机值,当前又有主键的影响,所以如何处理主键是的当务之急
4.优化脚本(主键信息
先将我们的主键信息拿到,在 3.1步骤中我们已经拿到了表的主键信息。所以接下来处理一下就行了
4.1 添加Beshell后置处理器
- 1.添加Beshell 后置处理器
- 2.拿到结果
import org.apache.jmeter.util.JMeterUtils;
String Info = prev.getResponseDataAsString();
String[] key_list = Info.split("\n");
List keyList = new ArrayList();
for (int i = 1; i < key_list.length; i++) {
keyList.add(key_list[i]);
}
String keys = String.join(",", keyList);
vars.put("keys",keys);
log.info("kkkkkey ========== > " + keys);
4.2 优化拼接数据请求(1)
需要在 generateSql方法中新增一个key_list,将主键信息传入,方便识别,修改代码的结构
import java.util.ArrayList;
import java.util.List;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class SqlGenerator {
public static String generateSql(List field_name_list, List field_type_list, List primary_key) {
StringBuilder sb = new StringBuilder();
sb.append("INSERT INTO ${database_name}.${table_name} (");
log.info("这是主键信息...... " + primary_key);
log.info("这是主键信息...... " + field_type_list);
log.info("这是主键信息...... " + field_name_list);
// 添加字段名称
for (int i = 0; i < field_name_list.size(); i++) {
sb.append(field_name_list.get(i));
if (i != field_name_list.size() - 1) {
sb.append(", ");
}
}
sb.append(") VALUES (");
// 根据字段类型添加对应的值
for (int i = 0; i < field_name_list.size(); i++) {
String type = field_type_list.get(i);
String name = field_name_list.get(i);
// 判断是否为主键,如果是则赋值一个数据
if (primary_key.contains(name)) {
sb.append("1111");
} else {
if (type.equalsIgnoreCase("ROWID")) {
sb.append("NULL");
} else if (type.equalsIgnoreCase("INT") || type.equalsIgnoreCase("INTEGER") || type.equalsIgnoreCase("SMALLINT") || type.equalsIgnoreCase("TINYINT") || type.equalsIgnoreCase("BIGINT")) {
sb.append("${__Random(10,1000000,rang_int)}");
} else if (type.equalsIgnoreCase("NUMBER") || type.equalsIgnoreCase("DEC") || type.equalsIgnoreCase("DECIMAL") || type.equalsIgnoreCase("NUMERIC")) {
sb.append("${__Random(2,10000,)}.${__Random(0,1000,)}");
} else if (type.equalsIgnoreCase("FLOAT") || type.equalsIgnoreCase("REAL") || type.equalsIgnoreCase("DOUBLE") || type.equalsIgnoreCase("DOUBLE PRECISION")) {
sb.append("${__Random(2,10000,)}.${__Random(0,1000,)}");
} else if (type.equalsIgnoreCase("BINARY_FLOAT")) {
sb.append("${__Random(3,3000,)}.${__Random(0,10000,)}");
} else if (type.equalsIgnoreCase("BINARY_DOUBLE")) {
sb.append("${__Random(4,10000000,)}.${__Random(0,100,)}");
} else if (type.equalsIgnoreCase("CHAR") || type.equalsIgnoreCase("CHARACTER") || type.equalsIgnoreCase("NCHAR") || type.equalsIgnoreCase("NVARCHAR2") || type.equalsIgnoreCase("VARCHAR") || type.equalsIgnoreCase("VARCHAR2")) {
sb.append("'${__RandomString(20,abcdefghijklmnopqrstuvwxyz90,)}'");
} else if (type.equalsIgnoreCase("TIMESTAMP") || type.equalsIgnoreCase("TIMESTAMP WITH LOCAL TIME ZONE")) {
sb.append("TO_TIMESTAMP('${__time(yyyy-MM-dd HH:mm:ss,time)}.000000', 'yyyy-mm-dd hh24:mi:ss.ff')");
} else if (type.equalsIgnoreCase("TIMESTAMP(6)")) {
sb.append("TO_TIMESTAMP('${__time(yyyy-MM-dd HH:mm:ss,time)}.000000', 'yyyy-mm-dd hh24:mi:ss.ff')");
} else if (type.equalsIgnoreCase("TIMESTAMP(6) WITH TIME ZONE")) {
sb.append("TO_TIMESTAMP_TZ('${__time(yyyy-MM-dd hh:mm:ss,time)}.000000 +08:00', 'yyyy-mm-dd hh24:mi:ss.ff tzr')");
} else if (type.equalsIgnoreCase("DATE") || type.equalsIgnoreCase("DATETIME WITH TIME ZONE")) {
sb.append("TO_DATE('${__RandomDate(,2022-04-23,2023-04-23,,)}', 'yyyy-mm-dd')");
} else if (type.equalsIgnoreCase("INTERVAL YEAR TO MONTH")) {
sb.append("INTERVAL '${__Random(1,12,)}-${__Random(1,12,)}' YEAR TO MONTH");
} else if (type.equalsIgnoreCase("INTERVAL YEAR")) {
sb.append("INTERVAL '${__Random(1,12,)}' YEAR");
} else if (type.equalsIgnoreCase("INTERVAL MONTH")) {
sb.append("INTERVAL '${__Random(1,59,)}' MONTH");
} else if (type.equalsIgnoreCase("INTERVAL DAY")) {
sb.append("INTERVAL '${__Random(1,31,)}' DAY");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO HOUR")) {
sb.append("INTERVAL '${__Random(1,28,)} ${__Random(1,12,)}:${__Random(1,59,)}:${__Random(1,59,)}' DAY TO HOUR");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO MINUTE")) {
sb.append("INTERVAL '${__Random(1,12,)} ${__Random(1,59,)}:${__Random(1,59,)}' DAY TO MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO SECOND")) {
sb.append("INTERVAL '${__Random(1,28,)} ${__Random(1,12,)}:${__Random(1,59,)}:${__Random(1,59,)}' DAY TO SECOND");
} else if (type.equalsIgnoreCase("INTERVAL HOUR")) {
sb.append("INTERVAL '${__Random(1,12,)}' HOUR");
} else if (type.equalsIgnoreCase("INTERVAL HOUR TO MINUTE")) {
sb.append("INTERVAL '${__Random(1,12,)}:${__Random(1,59,)}' HOUR TO MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL HOUR TO SECOND")) {
sb.append("INTERVAL '${__Random(1,12,)}:${__Random(1,59,)}:${__Random(1,59,)}' HOUR TO SECOND");
} else if (type.equalsIgnoreCase("INTERVAL MINUTE")) {
sb.append("INTERVAL '${__Random(1,59,)}' MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL MINUTE TO SECOND")) {
sb.append("INTERVAL '${__Random(1,12,)}:${__Random(1,59,)}' MINUTE TO SECOND");
} else if (type.equalsIgnoreCase("INTERVAL SECOND")) {
sb.append("INTERVAL '${__Random(1,59,)}' SECOND");
} else if (type.equalsIgnoreCase("INTERVAL DAY TO SECOND(6)")) {
sb.append("INTERVAL '${__Random(1,31,)} 12:34:56.789' DAY TO SECOND(3)");
} else if (type.equalsIgnoreCase("INTERVAL DAY(2) TO HOUR")) {
sb.append("INTERVAL '${__Random(1,31,)} ${__Random(1,12,)}' DAY TO HOUR");
} else if (type.equalsIgnoreCase("INTERVAL DAY(2) TO MINUTE")) {
sb.append("INTERVAL '${__Random(1,31,)} ${__Random(1,23,)}:${__Random(1,59,)}' DAY TO MINUTE");
} else if (type.equalsIgnoreCase("INTERVAL YEAR(2) TO MONTH")) {
sb.append("INTERVAL '0${__Random(1,9,)}-0${__Random(1,9,)}' YEAR TO MONTH");
} else if (type.equalsIgnoreCase("INTERVAL DAY(2) TO SECOND(6)")) {
sb.append("INTERVAL '+2 0${__Random(1,9,)}:${__Random(1,59,)}:${__Random(1,59,)}.250000' DAY(2) TO SECOND(6)");
} else if (type.equalsIgnoreCase("BLOB")) {
sb.append("empty_blob()");
} else if (type.equalsIgnoreCase("CLOB")) {
sb.append("'test clob ${__RandomString(9,ERTYuzvbndm12,)}'");
} else if (type.equalsIgnoreCase("RAW")) {
sb.append("'${hexString}'");
} else {
sb.append("''");
}
}
if (i != field_type_list.size() - 1) {
sb.append(", ");
}
}
sb.append(")");
return sb.toString();
}
}
// 获取上个请求的表结构
String Info = prev.getResponseDataAsString();
String[] AAA = Info.split("\n");
// 拼接sql字段名跟字段类型
List field_name_list = new ArrayList();
List field_type_list = new ArrayList();
for(int i=1;i<AAA.length;i++){
String[]fields=AAA[i].split("\t");
String field_name=String.valueOf(fields[0]);
field_name_list.add(field_name);
String field_type=String.valueOf(fields[1]);
field_type_list.add(field_type);
}
// 传入主键的字段信息
String key_list = "${keys}";
log.info("sssssss " + key_list);
String[] AAA = key_list.split(",");
// log.info("怎么个事儿? " + Arrays.toString(AAA));
List field_key_list = new ArrayList();
for (int i=0; i<AAA.length; i++) {
//log.info(AAA[i]);
field_key_list.add(AAA[i]);
}
// log.info(field_key_list.toString());
// 生成 SQL 语句
String sql=SqlGenerator.generateSql(field_name_list,field_type_list,field_key_list);
log.info("INSERT SQL ====>"+sql);
vars.put("sql",sql);
这样是不是就万物一失了?我们试试
啊哦 好像还是报错唯一值,这是为啥呢?还是我们说的随机数可能存在重复。但是oracle又不像mysql数据库有自增的主键信息,哦对了,那我们创建一个可以自增的数据不就行了吗?oracle的序列就支持这种自增的情况
4.3 新增序列信息
- 1.创建一个序列,每生成一条数据的时候只要next一下序列名就可以拿到一个不重复的值! 这也太棒了
CREATE SEQUENCE MK_SV_ET_DATA_LIST_S
START WITH 1
INCREMENT BY 1
MINVALUE 1 NOMAXVALUE; -- 不设置最大值
2.创建好序列
3.手动调用序列
MK_SV_ET_DATA_LIST_S.nextval
4.4 优化拼接数据请求(2)
- 1.替换主键的插入值为序列
- 2.请求数据,插入成功
在这里脚本会自动拿到最新的一条数据,至此插入脚本结束;
5.批量插入数据
5.1 插入数据编写
BEGIN
FOR I IN 1..10000
LOOP
${sql};
IF MOD(I,1000)=0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;
将jdbc请求替换掉,就可以批量插入数据啦
5.总结
在这个过程中遇到了很多问题,因为太久没用java导致一些内容写的也不是很好,处理方式也没有很完美,这也说明了凡事都要回顾,温故而知新。最重要的是思路,有些东西构思好了,操作起来就舒服了。