简体   繁体   中英

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.

This is now taking the form of a foreach loop, and building up the query based on what feeds through

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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