Powershell--批量拆分SQL语句为事务并批处理

作为DBA,时不时会遇到将数据导入到数据库的情况,假设业务或研发提供一个包含上百万行INSERT语句的脚本文件,而且这些INSERT 语句没有使用GO来进行批处理拆分,那么直接使用SQLCMD来执行会发现该进程消耗大量物理内存并迟迟没有数据写入,即使脚本中每一行都添加了GO,你依然会发现这插入效率太差,让你无法忍受,怎么搞呢,下面小代码帮你折腾下:

$old_file_path= ‘C:\insert_scripts.sql‘
$new_file_path=‘C:\insert_scripts_new.sql‘
$tran_rows=50

$line_content="
SET NOCOUNT ON
GO
BEGIN TRAN
BEGIN TRY
"
$line_content |Out-File $new_file_path
$line_num=1

$sr1=[IO.StreamReader]$old_file_path
$line_content=""
while(-not $sr1.EndOfStream)
{

    $tmp_content= $sr1.ReadLine()
    $line_content=$line_content+"`r"+$tmp_content
    $line_num_mode =$line_num % $tran_rows

    if($line_num_mode -eq 0)
    {
        $line_content=$line_content+"
COMMIT
PRINT ‘执行第"+($line_num-$tran_rows)+"行到第"+($line_num)+"行成功‘
END TRY
BEGIN CATCH
ROLLBACK
PRINT ‘执行第"+($line_num-$tran_rows)+"行到第"+($line_num)+"行失败‘
END CATCH
GO
BEGIN TRAN
BEGIN TRY
"
        $line_content | Out-File -Append $new_file_path
        Write-Host "处理到行" $line_num
        $line_content=""
    }

    $line_num=$line_num+1

}

$line_content=$line_content+"
COMMIT
PRINT ‘执行第"+($line_num-$tran_rows)+"行到第"+($line_num)+"行完成‘
END TRY
BEGIN CATCH
ROLLBACK
PRINT ‘执行第"+($line_num-$tran_rows)+"行到第"+($line_num)+"行失败‘
END CATCH
GO
"
$line_content | Out-File -Append $new_file_path

$sr1.Close()

还是看点疗效吧,原始SQL为:

经过此脚本修改过的变为:

这样实现有以下有点:

1.  使用“SET NOCOUNT ON”来屏蔽每条语句返回影响行数,减少与cmd窗口交互的次数;

2.  将每50条语句拆分到一个批处理中,降低数据库进行语法检查分析的消耗,在封装到一个事务中进行提交,减少写日志的次数;

3.  打印输出事务执行结果,方便排查错误(可修改代码只输出执行失败的事务)

执行结果截图:

====================================================

在个人电脑测试,以100条一个事务来拆分,大概1分钟可以导入50万到60万,按不同的行数进行拆分插入效率不同,具体合适的拆分行数需要根据实际情况测试为准。

对于超大数据量的导入,还是推荐使用csv+bcp的方式来导入,INSERT+SQLCMD的效率始终太低太低!

====================================================

没啥技术含量,厚脸拿出来分享,只是因为很久没写博客啦!

时间: 2024-10-12 11:24:54

Powershell--批量拆分SQL语句为事务并批处理的相关文章

SQL*PLUS中批量执行SQL语句

SQL*PLUS中批量执行SQL语句 今天由于工作的需要,要在CMD中批量执行大量的SQL语句,对于Oracle学习还处在入门阶段的我,只能硬着头皮到处去寻找资料(主要是网络资料,也包括自己的电子书),最后将所有的SQL语句一次性的执行完成. 首先,将要执行的所有的SQL语句,全部写入某个sql文件当中.例如f:\test.sql; 然后,通过通过sqlplus连接到数据库:如: SQL> sqlplus test/[email protected]; 再执行如下命令: SQL> @f:\te

带参方法的执行:普通方法的查询,可为空方法的查询。批量处理SQL语句。

普通方法的查询: @Override public List<Map<String, Object>> selectSpentAmount(Integer MAT_TYPE_, String DEPT_CODE_, Integer YEAR_, Map<String, Object> operator) { String sql = "select MAT_NO_, sum(AMOUNT_) as SPENT_AMOUNT_ from DM_MAT_MONTH

mysqli扩展库应用---批量执行sql语句

1, mysqli批量执行sql语句.基本语法: $sqls=”sql1;sql2;………” mysqli::multi_query($sqls); 同一个$sqls要么是增删改语句集合,要么是查询语句的集合,查询语句和增删改最好不要混合.应用示例如下: ① 操作数据库的代码: <?php class mysqliMutiTool{ private $mysqli = null; private static $host = "10.252.158.217"; private s

批量执行sql语句

基本使用 $sqls="sql语句1;sql语句2;sql语句n"; 或 $sqls="insert into xx;";  $sqls.="insert into xx;"; $res=mysqli::multi_query($sqls); 如果$sqls 是dml 语句,则$res 返回布尔值: 如果$sqls 是dql 语句,则$res 返回多个结果集,需要使用mysqli::store_result() 和 mysqli::more_re

JDBC连接MYSQL,批量执行SQL语句或在执行一个SQL语句之前执行一个SQL语句

conn = MysqlJdbcUtils.getConnection(); Statement ps=conn.createStatement(); ps.addBatch("truncate QB_ShowCount_Asite_copy"); ps.executeBatch(); String SrcSql = "select convert(unhex(hex(convert(Community using latin1))) using utf8) as Commu

JDBC_批量处理SQL语句

使用批处理有两个前提: 1. 首先要MySQL驱动支持批处理(我用的5.17) 2. 配置连接服务器的地址时,在后面加:?rewriteBatchedStatements=true 如: 相关API: addBatch:将SQL语句添加到批处理包 executeBatch:执行批处理包中的SQL语句 clearBatch:清空批处理包中的SQL语句 说明:批处理往往搭配preparedStatement使用:preparedStatement减少编译次数,批处理减少运行次数,效率大大提高 案例:

ThinkPHP3.2.3批量执行sql语句(带事务)

/*** 事务封装方法* @access public 将此方法放入框架model.class.php中* @param array $sqls 要执行的sql数组或语句* @param array $vals sql语句中要替换的值* @return boolean*/public function transExecuteSql($sqls){ $this->startTrans(); if(is_array($sqls)){foreach($sqls as $k => $sql){ $r

在Access中批量调用SQL语句

access的SQL视图一次只能执行一条SQL语句,那么在VBA中调用或许可以简便一些 例如: Public Sub 批量()Dim strsql As String   strsql = "INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)VALUES (804,'李诚','男','1958-12-02','副教授','计算机系');"CurrentProject.Connection.Execute strsqlstr

手把手教你-----巧用Excel批量生成SQL语句,处理大量数据

在做系统或者做项目的时候,经常会遇到这样的要求:用户给我们发过来一些数据,要求我们把这些数据导入到数 据库中,对于少量的数据来说,用最原始的方法就可以解决,直接在SQL里面用语句来实现,但是如果有成千上万条的 数据呢?如果你还继续单独写SQL语句,估计写个几十条你就会有跳楼的冲动,其实有两种简单的方法: 1.将Excel的数据整理好,通过SQL的导入功能直接导入到数据库中,但是要保证数据库的字段和Excel的字段一致. 2.通过Excel生成相应的SQL语句,然后,放到SQL的新建查询中,执行.