简体   繁体   English

用于动态大小删除和插入的SQL参数

[英]SQL parameters for dynamic size deletes and inserts

I have a service that copies data and does modifications etc. One of the functions is just straight replicating deletes and inserts across the databases which is fine and easily accomplished using Entity, unfortunately larger queries become quite slow so I'm looking to just run it as a raw SQL query. 我有一个可以复制数据并进行修改等的服务。功能之一就是直接在数据库中复制删除和插入操作,使用Entity可以轻松实现,但不幸的是,较大的查询变得相当慢,因此我希望直接运行它作为原始SQL查询。

This is now taking the form of a foreach loop, and building up the query based on what feeds through 现在,这采用了foreach循环的形式,并根据提供的内容建立查询

ie

if(deletes.Count() > 0) 
{
    // Build up delete string
    StringBuilder sqlCommand = new StringBuilder("DELETE FROM RandomTable WHERE ");

    List<string> rows = new List<string>();

    foreach(var item in query)
    {
        rows.Add(string.Format("(Key1 = '{0}' AND Key2 = '{1}' AND Key3 = '{2}' AND Key4 = '{3}' AND Key5 = '{4}')",
                               item.Key1, item.Key2, item.Key3, item.Key4, item.Key5));
    }

    sqlCommand.Append(string.Join(" OR ", rows));
    sqlCommand.Append(";");
    runyoubadthing(sqlCommand);
}

(please note, I am stripping quotes and junk, but not needed for this example) Now I know that they need to be parameterized (however the above is in a service that just talks between databases so technically shouldn't need it, but I'd still like to follow good practice). (请注意,我要删除引号和垃圾,但此示例不需要)。现在,我知道它们需要进行参数化(但是以上内容仅在数据库之间进行通信的服务中,因此从技术上讲不需要它,但是我仍然希望遵循良好的做法)。

My question is: how would I do the above in proper parameterized query where it could run as a single query instead of running as thousands of single deletes which would take a hell of a lot longer? 我的问题是:如何在适当的参数化查询中执行上述操作,使其可以作为单个查询运行,而不是作为数千个单个删除运行,这将花费更长的时间?

Side note: this whole ordeal would be about 1000 times better with a single auto incrementing ID, unfortunately this is not my database and now I have to deal with up to 10 primary key nightmares for finding unique data 旁注:使用单个自动递增ID可以使整个折磨过程提高大约1000倍,不幸的是,这不是我的数据库,现在我不得不处理多达10个主键梦night以查找唯一数据

You could try something like this: 您可以尝试这样的事情:

var Command = new SQLCommand {
    CommandText = "DELETE FROM RandomTable WHERE ",
    Connection = yourConnection
};
var count = 0;
foreach(var item in query)
{
    Command.CommandText += Command.CommandText.EndsWith("WHERE ")? "": "OR ";
    Command.CommandText += $"(Key1 = '@{count}0' AND Key2 = '@{count}1' AND Key3 = '@{count}2' AND Key4 = '@{count}3' AND Key5 = '@{count}4')";
    Command.Parameters.Add($"@{count}0", [YourDBType]).Value = item.Key1;
    Command.Parameters.Add($"@{count}1", [YourDBType]).Value = item.Key2;
    Command.Parameters.Add($"@{count}2", [YourDBType]).Value = item.Key3;
    Command.Parameters.Add($"@{count}3", [YourDBType]).Value = item.Key4;
    Command.Parameters.Add($"@{count}4", [YourDBType]).Value = item.Key5;
    count++;
}
Command.Prepare();
//Execute Command

I don't think that there is any better way to solve this problem other than executing a delete command for each item. 我认为除了对每个项目执行删除命令外,没有其他更好的方法来解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM