0

起初这可能看起来很奇怪,但我希望它是有道理的!我有一个list<string>mysql insert 语句,我遍历并逐个执行,这工作正常,但我想要实现的是性能提升。

例如,我想在单个查询中传递所有值而不是

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);

所以基本上我需要构建一个长查询字符串,将第一个查询作为起点,并将括号部分从值附加到末尾,无论列表中的对象数量是多少 - 这可能吗?

4

2 回答 2

2

这应该有效。我regex用来查找列和值并string.Substring查找表名。然后我把所有的string.Formatstring.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));

使用您的示例数据进行演示。

于 2013-01-24T10:25:02.577 回答
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());
于 2013-01-24T10:43:06.247 回答