记录更新或插入问题 返回

SqlSugar 老数据
6 2997

表结构

CREATE TABLE tLayoutPara(

[guid] [uniqueidentifier] NOT NULL,

[ParaName] [nvarchar](50) NOT NULL, --参数名

Host_guid uniqueidentifier NULL, --客户机

Line_guid uniqueidentifier NULL, --流水线

[ParaValue] [nvarchar](MAX) NULL) --参数值


代码部分:

封装了SqlSugarClient

public class DALAdvance : SqlSugarClient, IDAL.IDALAdvance

{

public DALAdvance(ConnectionConfig config) : base(config)

{

Aop.OnLogExecuting = (sql, paras) =>

{

mExecutionFailed = false;

ErrorMessage = "";

Debug.WriteLine(sql);

};

Aop.OnError = (exp) =>

{

mExecutionFailed = true;

ErrorMessage = exp.Message;

};

}


/// <summary>

/// 执行出错

/// </summary>

public bool ExecutionFailed { get { return mExecutionFailed; } }

protected bool mExecutionFailed = false;


/// <summary>

/// 错误信息

/// </summary>

public string ErrorMessage { get; protected set; }

}


使用部分:

var itm = new tLayoutPara()

{

guid = Guid.NewGuid(),

Host_guid = vusr.HostInfo.guid,

Line_guid = vpara.Line_guid,

ParaName = vpara.data.ParaName,

ParaValue = vpara.data.ParaValue

};

using var db = DALFactorySet.NewDALAdvance();

var x = db.Storageable(itm)

.WhereColumns(it => new { it.Host_guid, it.Line_guid, it.ParaName })

.ToStorage();

x.AsInsertable.ExecuteCommand();

x.AsUpdateable.UpdateColumns(it=>new { it.ParaValue }).ExecuteCommand();

if (db.ExecutionFailed)

rlt.msg = db.ErrorMessage;

else rlt.code = ResCode.OK;

return rlt;


调试输出,生成的脚本:

UPDATE [tLayoutPara]  SET

           [ParaValue]=@ParaValue  WHERE [Host_guid]=@Host_guid AND [Line_guid]=@Line_guid AND [ParaName]=@ParaName AND [Host_guid]=@Host_guid AND [Line_guid]=@Line_guid AND [ParaName]=@ParaName


问题:WHERE 条件重复两遍。



若要生成下面这样的,更新或插入脚本,怎么写

DECLARE

@paraName nvarchar(50),

@hostguid uniqueidentifier,

@lineguid uniqueidentifier,

@paraValue nvarchar(MAX)

SET NOCOUNT ON;

DECLARE @guid uniqueidentifier;

UPDATE TOP(1) tLayoutPara SET @guid=guid, ParaValue=@paraValue

WHERE ParaName=@paraName AND Host_guid=@hostguid AND Line_guid=@lineguid;

IF(@guid IS NULL)

BEGIN

SET @guid=NEWID();

INSERT INTO tLayoutPara(guid, ParaName, Host_guid, Line_guid, ParaValue )

VALUES(@guid, @paraName, @hostguid, @lineguid, @paraValue);

END







热忱回答6


  • 1 .wherecolumns并且你实体也带主键确实会存在相同条件,后续完善,目前不影响功能

    2.带有逻辑的功能,在下面基础上修改

    var x = Db.Storageable(list2)
              .SplitError(it => string.IsNullOrEmpty(it.Item.Name), "名称不能为空")
              .SplitUpdate(it => it.Any())//数据库存在更新 根据主键
              .SplitInsert(it => true )//其余插入
              .ToStorage();


    0 回复
  • 小杰 小杰 VIP0
    2021/8/27

    测试

    0 回复
  • @fate stay night:OK,谢谢!先这样处理了。



    0 回复
  • 上面最后关于脚本的问题是:

    插入或添加一条记录,条件是用业务字段判断,非表主键。

    第一种,先查询是否存在,存在则更新,不存在则插入。共执行三次语句

    第二种方式,直接使用更新 update top(1),同时可判断出记录是否存在,没有成功更新的记录,则插入。共执行两条语句

    在大数量和高并发时,第二种方式性能明显优于第一种。

    我的问题时,第二种方式如何用sugar写。


    0 回复
  • 你这是单条记录操作

    第一种情况

    会执行   1.查询  2 插入或者更新  只操作2次库   ,并且在有事务情况 你的查询可以锁住表 让MSSSQL事务默认级别达到预期效果


    第二种情况 1.更新 2插入或者不插入   操作 1-2次 必须有一次更新


    性能上差距不会太大,主要还是看你的查询条件是否全表扫描

    0 回复
  • @fate stay night:哦,不好意思。说错了,一次2次,二是1或2次

    0 回复