使用 sqlbulktools 更新表时对列值求和

Posted

技术标签:

【中文标题】使用 sqlbulktools 更新表时对列值求和【英文标题】:Sum column value while updating table using sqlbulktools 【发布时间】:2021-01-14 12:31:29 【问题描述】:

我正在使用 SqlBulkTools nuget 包来更新数百行数据。我在网上找到的示例涉及指定复制到表中的特定值。

是否可以将值添加/求和到现有存储值?例如假设列“计数”的值为 200。我想将其更新 128,是否可以使用 SqlBulkTools?

【问题讨论】:

【参考方案1】:

SqlBulkTools 的主要用例是将数据直接导入数据库,因此不会有任何功能或事件可让您直接定义要在批量操作期间执行的操作。 BuildPreparedDataTable() 可能是你要找的,但我以前从未使用过,所以我不能自信地说。

相反,您最好的选择是在将数据与 SqlBulkTools 挂钩之前对其进行修改。您可以通过多种方式完成此操作。

    放弃 SqlBulkTools,改用存储过程。 使用 LINQ 直接翻译。 设置 AutoMapper,然后创建您自己的 IValueResolver。

选项1:存储过程

虽然不使用 SqlBulkTools,但这可能是最简单和最有效的选项,因为您可以引用正在更新的表。

CREATE PROCEDURE dbo.Add128ToCount
    @StartDate DATETIME,
    @EndDate DATETIME
AS
BEGIN
    SET NOCOUNT ON;
    
    UPDATE st SET [Count] = st.[Count] + 128
    FROM dbo.SomeTable st
    WHERE st.LastModifiedDate BETWEEN @StartDate AND @EndDate;
END

对于那些需要在表之间而不是同一个表进行某种数据修改的人,创建一个与表结构匹配的用户定义表类型,然后使用该类型将表值参数添加到存储过程. (More Information)

CREATE PROCEDURE dbo.Add128ToCount
    @TVP SomeOtherTableType READONLY
AS
BEGIN
    SET NOCOUNT ON;
    
    INSERT INTO dbo.SomeTable
    (
        Name,
        [Count]
    )
    SELECT Name,
        [Count] + 128 AS [Count]
    FROM @TVP;
END

选项 2:LINQ

如果您必须使用 SqlBulkTools(例如,如果您没有数据库访问权限),您可以使用 LINQ 完成与选项 1 相同的事情。 (More Information)

List<DestType> dest = (from s in source
                       select new DestType
                       
                           Id = s.Id,
                           Name = s.Name,
                           Count = s.Count + 128
                       ).ToList();

选项3:AutoMapper IValueResolver

如果您只需要执行一次类似的操作,则此选项将是多余的,因为涉及很多设置,包括配置 AutoMapper 和定义配置文件。但是,在您使用多个表甚至多个数据库的情况下,这是一个很好的长期解决方案。对于此处的特定用例,您的个人资料将如下所示:

class SomeTableProfile : Profile

    public SomeTableProfile()
    
        SourceMemberNamingConvention = new PascalCaseNamingConvention();
        DestinationMemberNamingConvention = new PascalCaseNamingConvention();
        CreateMap<SourceType, DestType>()
            .ForMember(dest => dest.Count, opt => opt.MapFrom<Add128ToCountResolver>());
    

然后,您将制作一个自定义 IValueResolver,如下所示:

class Add128ToCountResolver : IValueResolver<SourceType, DestType, int>

    public int Resolve(SourceType source, DestType destination, int destCount, ResolutionContext context)
    
        return source.Count + 128;
    

(More About AutoMapper) (More About Value Resolvers)

【讨论】:

以上是关于使用 sqlbulktools 更新表时对列值求和的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL 在字段更改时运行总计(仅在字段更改时对列求和)

基于多索引对列值求和

创建视图并对列值进行求和

根据可变日期范围(impala)在窗口上对列值求和

基于一周范围的窗口对列值求和(黑斑羚)

Pandas:如何根据其他列值的条件对列进行求和?