软删除的存储过程

Posted

技术标签:

【中文标题】软删除的存储过程【英文标题】:Stored Procedure For A Soft Delete 【发布时间】:2014-01-10 20:23:44 【问题描述】:

此代码用于执行软删除。 它首先删除一条记录。如果删除成功,则回滚并更新同一记录的标志列。如果该记录具有依赖关系并且无法删除,则不执行任何操作。为了知道动作发生了,我保留了 Status 变量。 但是,无论如何,它总是结果为空。我哪里错了。

ALTER PROCEDURE SoftDelete
(
  @TableName nvarchar(50), @ColName nvarchar(50),
  @Id nvarchar(50)
)
AS
BEGIN
  DECLARE @qryDel nvarchar(MAX),@qryUpd nvarchar(MAX),@Status int = null,
          @Param  nvarchar(MAX)

  SET @Param = N'@TableName nvarchar(50), @ColName nvarchar(50),
                @Id nvarchar(50)'
  SET @qryDel = N'delete from @tablename where @colname=@id'
  SET @qryUpd = N'update @tablename set deleted = 1 where @colname=@id'

  BEGIN TRY
    BEGIN TRANSACTION
      EXECUTE sp_executesql @qryDel, @Param, @TableName, @ColName, @Id
    ROLLBACK TRANSACTION
    BEGIN TRANSACTION
      EXECUTE sp_executesql @qryUpd, @Param, @TableName, @ColName, @Id
    COMMIT TRANSACTION
    SET @Status = 1
  END TRY

  BEGIN CATCH
    ROLLBACK TRANSACTION
    SET @Status = 0
  END CATCH

  SELECT @Status

END

C#:(Linq 到实体)

public int SoftDelete()

  return MYDB.SoftDelete("tblCountry","CountryId,"101").FirstOrDefault ?? -1;

【问题讨论】:

您的数据库当前的事务隔离级别是多少?请参阅此帖子以轻松确定***.com/questions/1038113/… 对不起,这对我来说太远了。我不认为,我可能可以帮助你一些需要的答案。谢谢你 你所有的变量都是NVARCHAR类型的——并且为了表明你使用的是Unicode字符串,你应该在这些字符串文字前加上N!使用这个:SET @qryDel = N'delete from @tablename where @colname=@id' 准确和清晰 做到了。还是一样。全部为 0。 @Ruby:@Param 似乎还没有 N 前缀(至少在您的帖子中) 【参考方案1】:

你只是缺少空格...

鉴于此:

'delete from'+@tablename+'

当您尝试从 tblCountry 中删除时,您会得到

delete fromtblCountry

您需要在from 关键字和表变量之间添加一个空格

使用这个:

'delete from '+@tablename+'
            ^
            +------- crucial **SPACE** here!!

但是为什么哦为什么您首先实际删除该行,回滚该事务,然后才进行“软删除”?对我来说没有任何意义......

【讨论】:

我怀疑@ruby 希望 SQL 引擎为他们检查删除冲突(FK 等),因此他们可以知道软删除是否对“软”关系完整性有效.这是一个聪明的技巧,这意味着它可能很危险:我不确定如果存在包含事务会发生什么(因为 SQL Server 不支持“真正的”嵌套事务)。 没错,但我不知道嵌套事务。能否举个简单的例子: 也同意marc_s,但在这个层面上,我发现这个更简单。 @Ruby:对于嵌套事务的内部事务,COMMIT 被忽略,未命名的 ROLLBACK 将回滚 所有 嵌套事务。如果您在这里命名您的内部事务,您可能能够在嵌套时使其正常工作(不确定)。见这里:technet.microsoft.com/en-us/library/ms189336(v=sql.105).aspx @gotqn 您必须询问 Ruby 才能确定,但​​大概在插入时,他们也会检查这一点(即,如果此记录标记为删除,则不允许插入)。至于这一切的意义何在,我的猜测是他们出于历史/存档目的保留“已删除”的记录。

以上是关于软删除的存储过程的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中调用 Oracle 存储过程时如何避免核心转储

MySQL存储过程查询和删除的问题

oracle 存储过程详细介绍(创建,删除存储过程,参数传递等)

[MSSQL]批量删除表名包含某字符串的数据表&批量删除存储过程包含某字符串的存储过程

如何在存储过程中删除一张表,表名是作为参数传入的

Oracle 存储过程 删除表记录时删除不存在的记录也是显示删除成功