与ExecuteSqlCommand一起使用的原始SQL查询在多个记录中不起作用

问题描述 投票:0回答:2

我正在尝试在更新多个记录时有效地使用UPDATE查询(而不是为每个Id循环)。

我有这个简单的方法:

    public static async Task EfficientlyUpdateSentTimeforSomeTicketsAsync(List<int> Ids)
    {
        var parameters = Ids.Select((id, index) => new SqlParameter(string.Format("@p{0}", index), id));
        var parameterNames = string.Join(", ", parameters.Select(p => p.ParameterName));
        var query = string.Format("Update [TicketQueueTable] Set SentDatetime = {1} WHERE TicketQueueID IN ({0})", parameterNames, DateTime.Now);

        try
        {
            using (var db = GetDbContext())
            {
                var affectedRows = await db.Database.ExecuteSqlCommandAsync(query, parameters.ToArray());
            }
        }
        catch (Exception ex)
        {
            await LogErrorAsync(ex);
            throw ex;
        }
    }

我从以下SO问题获得帮助:https://stackoverflow.com/a/43969812/8644294,但无法完成这项工作。它让我大吃一惊,说:

[2附近的语法不正确]

为简单起见,我现在要发送的ID为new List<int>() { 1, 2 }

谢谢您的时间。

c# sql asp.net entity-framework dbcontext
2个回答
3
投票

您正在创建的字符串看起来像这样

Update [TicketQueueTable] Set SentDatetime = 3/6/2020 2:30:18 AM WHERE TicketQueueID IN (@p0, @p1)

如果尝试使用类似SQL Server Management Studio的sql工具执行该命令,则会出现此错误。

Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '2'.

加上凌晨2:30:18的2加上红色下划线。


您有两个选择:

  1. 引用日期时间
var query = string.Format("Update [TicketQueueTable] Set SentDatetime = '{1}' WHERE TicketQueueID IN ({0})", parameterNames, DateTime.Now);
  1. 使用SQL函数获取SQL服务器的当前时间
var query = string.Format("Update [TicketQueueTable] Set SentDatetime = GETDATE() WHERE TicketQueueID IN ({0})", parameterNames, DateTime.Now); // GETDATE() for MSSQL NOW() for MySQL
  1. 传递日期时间作为参数
public static async Task EfficientlyUpdateSentTimeforSomeTicketsAsync(List<int> Ids)
{
    var parameters = Ids.Select((id, index) => new SqlParameter(string.Format("@p{0}", index), id)).ToList();
    var parameterNames = string.Join(", ", parameters.Select(p => p.ParameterName));
    var query = string.Format("Update [TicketQueueTable] Set SentDatetime = @p{1} WHERE TicketQueueID IN ({0})", parameterNames, parameters.Count());

    parameters.Add(new SqlParameter($"@p{parameters.Count()}", DateTime.Now));
    try
    {
        using (var db = GetDbContext())
        {
            var affectedRows = await db.Database.ExecuteSqlCommandAsync(query, parameters.ToArray());
        }
    }
    catch (Exception ex)
    {
        await LogErrorAsync(ex);
        throw ex;
    }
}

1
投票

诸如此类:(我没有测试,可能有错字)

var parameterNames = string.Join(", ", Ids.Select(p => "("+ x.id.ToString()+")"));
var query = string.Format(@"Update TicketQueueTable 
                              Set SentDatetime = '{1}'
                             FROM TicketQueueTable
                             JOIN (
                               VALUES
                                {0}
                             ) AS L(ID) ON TicketQueueTable.Ticket.TicketQueueID = L.ID;", parameterNames, DateTime.Now)

如果要使用参数(应使用),则将其设为表参数,并在表中包含值列表,然后将其连接。

© www.soinside.com 2019 - 2024. All rights reserved.