c#sqlite 求教 批量插入,该怎么解决

c#sqlite 求教 批量插入,该怎么解决,第1张

private void btnImport_Click(object sender, EventArgs e)

{

string filePath = textBox1.Text

string importPwd = txtPwd.Text

if (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(importPwd))

{

MessageBox.Show("请先导入文件,填写 *** 作密码后,再 *** 作!")

}

else

{

btnImport.Text = "正在导入..."

btnImport.Enabled = false

string[] allLines = File.ReadAllLines(filePath)

using (SQLiteConnection con = new SQLiteConnection(connStr))

{

con.Open()

DbTransaction trans = con.BeginTransaction()//开始事务

SQLiteCommand cmd = new SQLiteCommand(con)

try

{

for (int n = 0n <allLines.Lengthn++)

{

cmd.CommandText = "insert into imei(imei) values(@imei)"

cmd.Parameters.Add(new SQLiteParameter("@imei", DbType.String))

cmd.Parameters["@imei"].Value = allLines[n]

cmd.ExecuteNonQuery()

}

trans.Commit()//提交事务

MessageBox.Show("文件导入成功!")

}

catch (Exception ex)

{

trans.Rollback()

MessageBox.Show("文件导入错误,请检查是否重复导入或其它原因!")

}

finally

{

btnImport.Text = "导 入"

btnImport.Enabled = true

}

}

}

}

/// <summary>

/// 使用SqlBulkCopy批量插入,只限SQLServer,超大数据量快速导入

/// 缺点,没有返回行数

/// </summary>

/// <param name="table">填充的DataTable,支持其它数据源,请看重载</param>

/// <param name="tableName">数据库对应表名</param>

/// <param name="columns">插入表对应的列名集合</param>

public void SqlBulkCopyInsert(DataTable table, string tableName, string[] columns)

{

SqlBulkCopy sbc = new SqlBulkCopy("接连字符串")

sbc.DestinationTableName = tableName

foreach (string col in columns)

{

sbc.ColumnMappings.Add(col, col)

}

sbc.WriteToServer(table)

}

/// <summary>

/// 多行插入,Connection/Command/DataAdapter看你连接的数据库类型

/// 进行相应的替换即可

/// </summary>

/// <param name="ds">填充数据后的数据集</param>

/// <returns>受影响行数</returns>

public int MultyInsert(DataSet ds)

{

int result = 0

IDbConnection con = new OracleConnection("连接字符串")

con.Open()

IDbCommand cmd = new OracleCommand()

cmd.CommandText = "Insert into Member(UserName,Password) values(@name,@password)"

IDbDataParameter namePar = cmd.CreateParameter()

namePar.ParameterName = "@name"

namePar.SourceColumn = "UserName"

namePar.SourceVersion = DataRowVersion.Original

namePar.DbType = DbType.String

cmd.Parameters.Add(namePar)

IDbDataParameter passPar = cmd.CreateParameter()

passPar.ParameterName = "@pass"

passPar.DbType = DbType.String

passPar.SourceColumn = "Password"

passPar.SourceVersion = DataRowVersion.Original

cmd.Parameters.Add(passPar)

IDbDataAdapter adpt = new OracleDataAdapter()

adpt.InsertCommand = cmd

try

{

result = adpt.Update(ds)

}

catch (Exception)

{

throw

}

finally

{

con.Close()

}

return result

}

/*

* Oracle中非常强大快速的数据批量 *** 作方法

*/

////引用

//using System.Data

//using System.Data.OracleClient

//using Oracle.DataAccess.Client//Oracle自带数据访问组件 位置: $Oracle安装路径$/bin/Oracle.DataAccess.dll

//设置一个数据库的连接串

string connectStr = "User Id=scottPassword=tigerData Source="

OracleConnection conn = new OracleConnection(connectStr)

OracleCommand command = new OracleCommand()

command.Connection = conn

//到此为止,还都是我们熟悉的代码,下面就要开始喽

//这个参数需要指定每次批插入的记录数

int recc = 10000000

command.ArrayBindCount = recc

//在这个命令行中,用到了参数,参数我们很熟悉,但是这个参数在传值的时候

//用到的是数组,而不是单个的值,这就是它独特的地方

command.CommandText = "insert into dept values(:deptno, :deptname, :loc)"

conn.Open()

//下面定义几个数组,分别表示三个字段,数组的长度由参数直接给出

int[] deptNo = new int[recc]

string[] dname = new string[recc]

string[] loc = new string[recc]

// 为了传递参数,不可避免的要使用参数,下面会连续定义三个

// 从名称可以直接看出每个参数的含义,不在每个解释了

OracleParameter deptNoParam = new OracleParameter("deptno", OracleType.Int32)

deptNoParam.Direction = ParameterDirection.Input

deptNoParam.Value = deptNo

command.Parameters.Add(deptNoParam)

OracleParameter deptNameParam = new OracleParameter("deptname", OracleType.VarChar)

deptNameParam.Direction = ParameterDirection.Input

deptNameParam.Value = dnamecommand.Parameters.Add(deptNameParam)

OracleParameter deptLocParam = new OracleParameter("loc", OracleType.VarChar)

deptLocParam.Direction = ParameterDirection.Input

deptLocParam.Value = loc

command.Parameters.Add(deptLocParam)

//在下面的循环中,先把数组定义好,而不是像上面那样直接生成SQL

for (int i = 0i <recci++)

{

deptNo[i] = i

dname[i] = i.ToString()

loc[i] = i.ToString()

}

//这个调用将把参数数组传进SQL,同时写入数据库

command.ExecuteNonQuery()

用SQLITE插入商品数据,发现才500条 就需要10多秒时间,太慢了。后来查了一下原因。如下:

大量插入数据 SQLITE插入一条数据,事务就会被反复地开启、关闭,会增大IO量。如果在插入数据前显式开启事务,插入后再一起提交,则会大大提高IO效率,进而加数据快插入速度。

根据测试结果:不预先开启事务,效率20 条/s。预先开启事务效率34095条/s。

这个效率差距挺大的。

//预先开启事务

db.execDML("begin")

//提交并关闭事务

db.execDML("commit")

加上后,几百条商品数据1秒都不要 就插入完毕了,不错。

记录一下

在数据库的sql语句前加:"begin" 结束后加“commit”;

string strSql

strSql += "begin\n"

for (unsigned int i = 0 i <v.Size()++i)

{

//unsigned int i = 0

const rapidjson::Value &val = v[i]

auto month = new MothData()

month->initWithDictionary(val)

strSql += StringUtils::format("INSERT INTO Car_mqpfl(father_code, organ_code, organ_name, report_name, stat_month,mqpfl_dn,mqpfl_qn,mqpfl_sn,xh) VALUES ('%s','%s', '%s', '%s','%s', '%s', '%s', '%s' , '%d')\n",month->father_code.c_str(),month->organ_code.c_str(),month->organ_name.c_str(),month->report_name.c_str(),month->stat_month.c_str(),month->mqpfl_dn.c_str(),month->mqpfl_qn.c_str(),month->mqpfl_sn.c_str(),month->xh)

}

strSql+= "commit\n"

SqlDB::insertData(strSql)

void SqlDB::insertData(std::string sql)

{

result = sqlite3_exec(_db, sql.c_str(), nullptr, nullptr, &errMsg)

if (result != SQLITE_OK) {

log("insert error , code = %d, message = %s\n",result,errMsg)

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/7841912.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存