1.MySQL批量插入数据
/*
利用MySQL存储过程批量创建MySQL的表:
test_1
test_2
test_...
*/
-- 如果存储过程已存在,先删除
DROP PROCEDURE IF EXISTS `createTables`;
-- 创建存储过程
-- 先自定义分隔符代付默认的分号分隔符、再创建存储过程,然后复默认分号分隔符,最后查询或执行存储过程
-- 注意:
-- 1.存储过程中包含多行、存在分号与默认的分隔符冲突,因此使用 DELIMITER 定义一个特殊的分隔符,遇到特殊分隔符才算语句的结束,才开始SQL解析和执行
-- 2.如果存储过程中的对象命名存在关键字冲突,则需要特殊符号(反引号)括起来
-- 3.MySQL中不要使用 CREATE OR REPLACE PROCEDURE,必须使用 CREATE PROCEDURE,Oracle中才支持 CREATE OR REPLACE PROCEDURE 语法
DELIMITER $$ -- 自定义分隔符
CREATE PROCEDURE `createTables`()
BEGIN
DECLARE `@i` int(11);
DECLARE `@createSql` VARCHAR(2560);
DECLARE `@createIndexSql1` VARCHAR(2560);
DECLARE `@createIndexSql2` VARCHAR(2560);
DECLARE `@createIndexSql3` VARCHAR(2560);
set `@i`=1;
WHILE `@i`<=4 DO
-- `M_ID` bigint AUTO_INCREMENT PRIMARY KEY NOT NULL,
-- createTable
SET @createSql = CONCAT('CREATE TABLE IF NOT EXISTS test_',`@i`,'(
`id` INT(11) NOT NULL COMMENT \'用户id\',
`name` VARCHAR(255) COMMENT \'用户名\',
`info` VARCHAR(255) COMMENT \'信息\',
`cnt` INT(11) DEFAULT 0 COMMENT \'计数\',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin');
prepare stmt from @createSql;
execute stmt;
SET `@i`= `@i`+1;
END WHILE;
END;
$$ -- 语句结束
DELIMITER ; -- 重新定义(恢复)默认的分号分隔符
-- 查询存储过程
SHOW CREATE PROCEDURE `createTables`;
-- 调用存储过程创建表
CALL createTables();
/* MySQL批量插入数据,举例 */
-- 如果存储过程已存在,先删除
DROP PROCEDURE test;
DELIMITER $$
CREATE PROCEDURE `test`()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE (i <= 10) DO
INSERT INTO `testdb`.`table01`(`id`,`name`) VALUES (i,'testaaaa');
SET i = i + 1;
END WHILE;
END;$$
DELIMITER ;
-- 调用存储过程
CALL test();
-- 如果写入大量的随机数据则:
DROP PROCEDURE insert_batch;
DELIMITER $$
CREATE PROCEDURE `insert_batch`()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE (i <= 10) DO
INSERT INTO `testdb`.`performance_test02_src_100w`(`id`,str01,str02,str03,str04,str05,str06,str07,str08,str09) VALUES (
i,
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 230)),
(select substr(repeat(substr(replace(uuid(),"-",""),1,32),8), 1, 208))
);
SET i = i + 1;
END WHILE;
END;$$
DELIMITER ;
-- 调用存储过程:写入表数据随机数据、单行大约2KB
CALL insert_batch();
/* MySQL批量插入数据,举例 */
-- 如果存储过程已存在,先删除
DROP PROCEDURE test;
DELIMITER $$
CREATE PROCEDURE test()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE (i<=10) DO
INSERT INTO test03.test_2(id,name,info) VALUES(i,'aaa','bbb');
SET i=i+1;
END WHILE;
COMMIT;
END $$
DELIMITER ;
-- 调用存储过程
CALL test();
表复制(方式创建表)和数据复制,基于已有的表复制:
-- for MySQL
-- 表复制(方式创建表)和数据复制,基于已有的表复制
-- 创建测试表
drop table if exists test;
create table test(
`dept` varchar(255) DEFAULT NULL,
`admin` varchar(255) DEFAULT NULL,
`logs` varchar(255) DEFAULT NULL,
`ctime` timestamp DEFAULT NOW()
)
drop table if exists test_02;
create table test_02(
`dept` varchar(255) DEFAULT NULL,
`admin` varchar(255) DEFAULT NULL,
`logs` varchar(255) DEFAULT NULL,
`ctime` timestamp DEFAULT NOW()
)
-- 构造测试数据
insert into test (dept,admin,logs,ctime) values ('dept01', 'user_A', 'aaa', '2025-08-07 13:10:00'), ('dept01', 'user_B', 'bbb', '2025-08-07 13:20:00');
insert into test (dept,admin,logs,ctime) values ('dept02', 'user_A', 'ccc', '2025-08-07 13:30:00'), ('dept02', 'user_B', 'ddd', '2025-08-07 13:40:00');
insert into test_02 (dept,admin,logs,ctime) values ('dept02', 'user_B', 'ddd', '2025-08-07 13:40:00');
-- 表1存在、但表2不存在(dept,admin)的数据
select t1.dept,t1.admin,t1.logs,t1.ctime from test t1, test_02 t2 where CONCAT(t1.dept, "_", t1.admin) != CONCAT(t2.dept, "_", t2.admin);
-- or
select t1.dept,t1.admin,t1.logs,t1.ctime from test t1 where CONCAT(t1.dept, "_", t1.admin) not in (select CONCAT(t2.dept,"_", t2.admin) from test_02 t2);
-- 基于已有表创建临时表(不复制数据,该方式不复制主键等约束)
drop table if exists test_tmp;
-- 加 where false(等效于 where 1 = 2)是为了不复制数据、而仅复制表结构
create table test_tmp select * from test where false;
desc test_tmp;
select * from test_tmp;
-- 基于已有表创建临时表(复制数据,该方式不复制主键等约束)
drop table if exists test_tmp;
create table test_tmp select * from test;
desc test_tmp;
select * from test_tmp;
-- 基于已有表创建临时表(该方式不复制数据,但会复制主键等约束)
drop table if exists test_tmp;
create table test_tmp like test;
desc test_tmp;
select * from test_tmp;
-- insert into select 方式批量插入数据
insert into test_tmp (dept,admin,logs,ctime) select dept,admin,logs,ctime from test;
desc test_tmp;
select * from test_tmp;
-- 清空临时表数据
truncate test_tmp;
-- 修改临时表、增加一列 idu 标记列、默认值固定为 "D"
alter table test_tmp add column idu varchar(1) default "D";
-- 查询(比较)表1存在、但表2不存在(dept,admin)的数据(比较量表获得 DELETE 数据)、插入临时表
insert into test_tmp (dept,admin,logs,ctime) select t1.dept,t1.admin,t1.logs,t1.ctime from test t1, test_02 t2 where CONCAT(t1.dept, "_", t1.admin) != CONCAT(t2.dept, "_", t2.admin);
select * from test_tmp;
2.Oarcle批量插入数据
# sys用户登录,grant execute on dbms_xxxx to xxx 来赋下权限才可以
# grant execute on dbms_output to USER01
# grant execute on dbms_lock to USER01
-- eg01
BEGIN
FOR i in 1 .. 2000
loop
INSERT INTO "USER01"."TABLE01" ("RYNBID", "COL02", "COL03", "COL04") VALUES (i, 'aaa', 'bbb', 'ccc');
END loop;
commit;
END;
/
-- eg02
BEGIN
FOR i in 1 .. 2000
loop
INSERT INTO "USER01"."TABLE01" ("RYNBID", "COL02", "COL03", "COL04") VALUES (i, 'aaa', 'bbb', 'ccc');
IF MOD(i,50) = 0 THEN
commit;
dbms_output.put_line('to commit, i = '||i||'');
dbms_lock.sleep(1);
END IF;
END loop;
commit;
END;
/
-- 注意:
-- 上面内容如果是直接在命令行终端执行、或者navicat都可以执行,但DBeaver无法执行。
-- 如果要在DBeaver中执行,必须创建存储过程、执行存储过程的方式,参考如下:
-- eg03
CREATE OR REPLACE PROCEDURE WRITEBATCH
IS
BEGIN
FOR i in 1 .. 1000000
loop
INSERT INTO "USER01"."TABLE01" ("RYNBID", "COL02", "COL03", "COL04") VALUES (i, 'aaa', 'bbb', 'ccc');
IF MOD(i,50000) = 0 THEN
commit;
END IF;
END loop;
commit;
END;
/
CALL WRITEBATCH();
-- 或者
BEGIN
WRITEBATCH();
END;
DROP PROCEDURE WRITEBATCH;
-- eg04
-- Oracle 批量生成随机内容测试数据(数据内容为随机值),FOR LOOP
-- CREATE OR REPLACE PROCEDURE MYPROC
-- IS
BEGIN
FOR i in 1 .. 1000000
LOOP
INSERT INTO "TEST"."TB_TEST01" ("ID", "STR01", "STR02", "STR03", "STR04", "STR05", "STR06", "STR07", "STR08", "STR09") VALUES (i, (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',230) FROM dual), (select DBMS_RANDOM.STRING('x',208) FROM dual));
IF MOD(i,50000) = 0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;
/
-- CALL MYPROC();
-- DROP PROCEDURE MYPROC;
-- eg05
-- Oracle 批量生成随机内容测试数据(数据内容为随机值,CNT为100~200范围内的随机值),FOR LOOP,并打印构造数据执行耗时时长
-- DBMS_UTILITY.GET_TIME 精确到1/00秒,例如: start_time: 481297262, end_time: 481301199, 执行耗时(s): 39.37
-- SET SERVEROUTPUT ON;
DECLARE
start_time NUMBER(38,0);
end_time NUMBER(38,0);
seconds NUMBER(38,2);
BEGIN
start_time := DBMS_UTILITY.GET_TIME;
FOR i in 1 .. 1000000
LOOP
INSERT INTO "TEST"."TB_TEST02" ("ID", "INFO", "CNT") VALUES (i, (select DBMS_RANDOM.STRING('x',50) FROM dual), (select DBMS_RANDOM.VALUE(100,200) FROM dual));
IF MOD(i,50000) = 0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
end_time := DBMS_UTILITY.GET_TIME;
seconds := (end_time - start_time)/100;
DBMS_OUTPUT.PUT_LINE(' ==> start_time: ' || start_time || ', end_time: ' || end_time || ', 执行耗时(s): ' || seconds);
END;
/
-- eg06
-- Oracle 批量生成随机测试数据(数据内容为随机值,CNT为100~200范围内的随机值),LOOP & EXIT WHEN,并打印构造数据执行耗时时长
-- DBMS_UTILITY.GET_TIME 精确到1/00秒,例如: start_time: 481297262, end_time: 481301199, 执行耗时(s): 39.37
-- SET SERVEROUTPUT ON;
DECLARE
start_time NUMBER(38,0);
end_time NUMBER(38,0);
seconds NUMBER(38,2);
i NUMBER(38,0) := 1;
i_max NUMBER(38,0) := 1000000;
BEGIN
start_time := DBMS_UTILITY.GET_TIME;
LOOP
INSERT INTO "TEST"."TB_TEST02" ("ID", "INFO", "CNT") VALUES (i, (select DBMS_RANDOM.STRING('x',50) FROM dual), (select DBMS_RANDOM.VALUE(100,200) FROM dual));
IF MOD(i,50000) = 0 THEN
COMMIT;
END IF;
i := i + 1;
EXIT WHEN i > i_max;
END LOOP;
COMMIT;
end_time := DBMS_UTILITY.GET_TIME;
seconds := (end_time - start_time)/100;
DBMS_OUTPUT.PUT_LINE(' ==> start_time: ' || start_time || ', end_time: ' || end_time || ', 执行耗时(s): ' || seconds);
END;
/
3.Oracle中批量删除多表
SELECT 'DROP TABLE ' || table_name || ';' FROM user_tab_comments WHERE table_name LIKE '%TESTJOB%';
4.PostgreSQL批量插入数据
1)PostgreSQL 批量插入数据(批量造数据、批量生成测试数据)
drop table test02;
create table test02(id int,info varchar(255),primary key(id));
insert into test02(id,info) select i,'test'||i from generate_series(1,100) as i;
select COUNT(*) from test02;
select * from test02 limit 10;
2)表复制(方式创建表)和数据复制,基于已有的表复制
-- 基于已有的表tableA创建相同表结构的表tableB(仅复制表结构、不复制数据)
drop table if exists tableB;
create table tableB like tableA;
-- 或者也可以下面这种方式:
drop table if exists tableB;
create table tableB select * from tableA where false;
-- 基于已有的表tableA创建相同表结构的表tableB(复制表结构、同时复制所有数据)
drop table if exists tableB;
create table tableB select * from tableA;
-- 基于已有的表tableA创建相同表结构的表tableB(复制表结构、同时复制部分数据)
drop table if exists tableB;
create table tableB select * from tableA where id<10;
-- A、B相同结构的两表已经存在时,将一张表的数据插入到另外一张表(B表中的数据插入A表)
insert into tableB select * from tableA where id<10;
-- SELECT INTO 将查询结果集插入到目的表(该方式貌似MySQL不支持):
SELECT id,info,cnt INTO test81_dst_d_tmp FROM test81_dst;
-- SELECT INTO 将查询结果集插入到目的表(MySQL能支持的方式)
DROP TABLE IF EXISTS test81_dst_d_tmp;
CREATE TABLE test81_dst_d_tmp
(
SELECT a.id,a.info,a.cnt,a.idu FROM test81 a,(
SELECT
id, MAX(ctimestamp)AS time
FROM test81
GROUP BY id
ORDER BY COUNT(*)DESC)b WHERE a.id=b.id AND a.ctimestamp=b.time AND a.idu='D'
);
5.SQL Server批量插入数据
-- SQLServer 批量插入表数据(方式1:普通循环插入)
-- 生成随机字符串方式:
-- NEWID生成随机的32位长度的uuid字符串,再通过REPLICATE重复4次增大长度,再SUBSTRING按需截取长度
-- 如果要生成随机数字:SELECT FLOOR(RAND()* 100000)
TRUNCATE TABLE test.test02;
DECLARE @i INT = 1
DECLARE @max INT = 20000
DECLARE @startTime DATETIME = GETDATE()
DECLARE @endTime DATETIME
DECLARE @cost INT
WHILE @i <= @max
BEGIN
INSERT INTO test.test02(id,str01,str02,str03,str04,str05,str06,str07,str08,str09)
VALUES (@i,
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)))
IF @i % 5000 = 0
PRINT CONCAT('process: ', @i, '/', @max)
SET @i = @i + 1
END
PRINT CONCAT('process finished: ', @max)
SET @endTime = GETDATE()
SET @cost = (SELECT DATEDIFF(MS, @startTime, @endTime))
PRINT CONCAT('执行耗时(ms): ', @cost)
-- 执行耗时(ms): 2230
-- SQLServer 批量插入表数据(方式2:开启事务循环插入,一次性提交,插入性能更高)
-- 生成随机字符串方式:
-- NEWID生成随机的32位长度的uuid字符串,再通过REPLICATE重复4次增大长度,再SUBSTRING按需截取长度
-- 如果要生成随机数字:SELECT FLOOR(RAND()* 100000)
TRUNCATE TABLE test.test02;
-- 开启事物
BEGIN TRANSACTION
DECLARE @i INT = 1
DECLARE @max INT = 20000
DECLARE @startTime DATETIME = GETDATE()
DECLARE @endTime DATETIME
DECLARE @cost INT
WHILE @i <= @max
BEGIN
INSERT INTO test.test02(id,str01,str02,str03,str04,str05,str06,str07,str08,str09)
VALUES (@i,
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)),
(select SUBSTRING(REPLICATE(NEWID(),4),1,113)))
IF @i % 5000 = 0
PRINT CONCAT('process: ', @i, '/', @max)
SET @i = @i + 1
END
PRINT CONCAT('process finished: ', @max)
SET @endTime = GETDATE()
SET @cost = (SELECT DATEDIFF(MS, @startTime, @endTime))
PRINT CONCAT('执行耗时(ms): ', @cost)
-- 提交事物
COMMIT
-- 执行耗时(ms): 433