sqllite批量插入
原文地址:https://stackoverflow.com/questions/9527851/sqlite-error-too-many-terms-in-compound-select
原文地址:http://blog.csdn.net/peakerli/article/details/9381013
原文地址:https://www.cnblogs.com/zhenjing/archive/2011/03/11/1981115.html
SQLLite批量插入数据
第一种:union 拼接插入
insert into 表名(列名1,列名2) select 值1,值2 union all select 值1,值2
db.execSQL("insert into radiomap(location,ap1,ap2) select 'x=1,y=1',-80,-73 " +
"union all select 'x=2,y=3',80,40 union all select 'x=3,y=5',30,20 "+
"union all select 'x=4,y=5',3,2 union all select 'x=30,y=50',30,20 union all select 'x=3,y=5',40,20"
+" union all select 'x=3,y=5',6,20 union all select 'x=3,y=5',6,7 union all select 'x=3,y=5',7,8"
);
第二种:直接插入
db.execSQL("insert into radiomap(location,ap1,ap2) values('x=7,y=8',7,8)");
db.execSQL("insert into radiomap(location,ap1,ap2) values('x=8,y=9',8,9)");
使用第一种方法+事务 效率较高。
注意点:
1)sqlite事务处理的问题,在sqlite插入数据的时候默认一条语句就是一个事务,有多少条数据就有多少次磁盘操作。原代码1000次插入起码开启了1000次读写磁盘操作。
SQLite的数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度。
2)使用了事务之后却是极大的提高了数据库的效率。但是我们也要注意,使用事务也是有一定的开销的,所以对于数据量很小的操作可以不必使用,以免造成而外的消耗。
3)第一种方法拼接union不能超过500条。
an error "too many terms in compound SELECT" occurs.

实际开发场景
将datatable中的数据插入到sqllite中。
1)数据>800条启用事务 <=800条拼接后直接插入
2)拼接语句400条执行一次插入操作
调用部分代码
SQLiteConnection myconn = null; try { myconn = new SQLiteConnection("DataSource=" + backPath); myconn.Open(); #region 2个线程备份数据 System.Threading.Thread[] thArr = new System.Threading.Thread[2]; thArr[0] = new System.Threading.Thread(() => { ExecuteNonQueryTran(myconn, UpBaseInfo()); ExecuteNonQueryTran(myconn, UpBatchInfo());
…………省略……… }); thArr[0].Start(); thArr[1] = new System.Threading.Thread(() => { ExecuteNonQueryTran(myconn, UpInMain()); ExecuteNonQueryTran(myconn, UpInList());
…………省略………
}); thArr[1].Start(); thArr[0].Join(); thArr[1].Join(); #endregion bResult = true; } catch (Exception exce) { throw new Exception("InsertError"); } finally { if (myconn != null && (myconn.State == ConnectionState.Open || myconn.State == ConnectionState.Broken)) { myconn.Close(); } }
/// <summary> /// 20171204批量插入数据(数据>800条启用事务) /// </summary> /// <param name="conn"></param> /// <param name="dt"></param> private void ExecuteNonQueryTran(SQLiteConnection conn, DataTable dt) { if (dt == null || dt.Rows.Count <= 0) { return; } int totalCount = dt.Rows.Count; //数据>800条启用事务 if (totalCount > 800) { SQLiteTransaction transaction = conn.BeginTransaction(); try { SQLiteCommand insertRngCmd = transaction.Connection.CreateCommand(); ExecuteDataTable(dt, insertRngCmd); transaction.Commit(); } catch (Exception e) { transaction.Rollback(); } } else { SQLiteCommand insertRngCmd = conn.CreateCommand(); ExecuteDataTable(dt, insertRngCmd); } }
/// <summary> /// 插入数据 /// </summary> /// <param name="dt"></param> /// <param name="insertRngCmd"></param> private void ExecuteDataTable(DataTable dt, SQLiteCommand insertRngCmd) { string field_s = ""; string field_v = ""; foreach (DataColumn dc in dt.Columns) { field_s += "," + dc.ColumnName.TrimEnd(); field_v += ",@" + dc.ColumnName.TrimEnd(); } string insertHead = "insert into " + dt.TableName.TrimEnd() + " (" + field_s.Substring(1) + ")"; StringBuilder insertValues = new StringBuilder(); for (int i = 0; i < dt.Rows.Count; i++) { string valueHead = " union all select "; //400条执行一次插入操作 if (i % 400 == 0) { valueHead = " select "; insertValues = new StringBuilder(); } //拼接值 string value = ""; foreach (DataColumn dc in dt.Columns) { value += ",'" + dt.Rows[i][dc.ColumnName].ToString() + "'"; } //构造一条数据 insertValues.Append(valueHead + value.Substring(1)); //400条执行一次插入操作 if ((i + 1) % 400 == 0) { string test = insertHead + insertValues.ToString(); insertRngCmd.CommandText = insertHead + insertValues.ToString(); insertRngCmd.ExecuteNonQuery(); } } //总条数不是400的倍数 if (dt.Rows.Count % 400 != 0 && insertValues.ToString().Length > 0) { string test = insertHead + insertValues.ToString(); insertRngCmd.CommandText = insertHead + insertValues.ToString(); insertRngCmd.ExecuteNonQuery(); } }

浙公网安备 33010602011771号