起初这看起来很奇怪,但我希望它有意义!我有一个list<string>
mysql插入语句,我迭代并逐个执行,这可以正常,但我想要实现的是性能提升。
我想在单个查询中传递所有值,例如而不是
INSERT INTO tb1(field1,field2,field3) VALUES (1,2,3);
INSERT INTO tb1(field1,field2,field3) VALUES (4,5,6);
INSERT INTO tb1(field1,field2,field3) VALUES (7,8,9);
我想做
INSERT INTO tb1(field1,field2,field3) VALUES (1,2,3), (4,5,6), (7,8,9);
所以基本上我需要构建一个长查询字符串,将第一个查询作为一个起点,并将括号部分从值附加到结尾,无论列表中的对象数量是多少 - 这可能吗?
答案 0 :(得分:2)
这应该有效。我使用regex
查找列和值,使用string.Substring
查找表名。然后我将所有内容与string.Format
和string.Join
以及简单的Linq查询放在一起:
IEnumerable<string> inserts = // add your insert-strings here;
string firstInsert = inserts.First();
int tableIndex = firstInsert.IndexOf("INSERT INTO ") + "INSERT INTO ".Length;
string table = firstInsert.Substring(
tableIndex, firstInsert.IndexOf("(", tableIndex) - tableIndex);
var regex = new System.Text.RegularExpressions.Regex(@"\(([^)]+)\)",System.Text.RegularExpressions.RegexOptions.Compiled);
string columns = regex.Matches(firstInsert)[0].Value;
IEnumerable<string> values = inserts.Select(sql => regex.Matches(sql)[1].Value);
string insertAll = string.Format("INSERT INTO {0}{1} VALUES {2};"
, table
, columns
, string.Join(",", values));
DEMO包含您的示例数据。
答案 1 :(得分:1)
以防您可能插入不同的表(或表中的列集),
var perTableQueries = separateQueries
.Select(s => s.Split(new[] {" VALUES "}, StringSplitOptions.None))
.Where(a => a.Length == 2)
.GroupBy(a => a[0], StringComparer.InvariantCultureIgnoreCase)
.Select(g => String.Format("{0} VALUES {1};",
g.Key,
String.Join(",", g.Select(a => a[1].TrimEnd(';')).ToArray())));
将为每个表/列集创建一个插入(如果您的SQL一致)。
也就是说,如果您为每条线路向数据库发出单独的请求,那么您最大的性能节省可能就是
var singleRequest = String.Join("", perTableQueries.ToArray());