仅从insert语句字符串中提取值?

时间:2013-01-24 10:03:33

标签: c# string linq c#-4.0

起初这看起来很奇怪,但我希望它有意义!我有一个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);

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

2 个答案:

答案 0 :(得分: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));

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