【问题标题】:Insert trigger for duplicate records not working sql server重复记录的插入触发器不起作用sql server
【发布时间】:2015-01-24 12:15:22
【问题描述】:
ALTER TRIGGER [dbo].[STOK_HARKETLERI_Insert]    
ON [dbo].[STOK_HAREKETLERI]              
FOR INSERT 
AS BEGIN  
    declare @tip int 
    declare @miktar float 
    declare @stokkod nvarchar 
    declare @tarih datetime 
    declare @counter int  

    Select 
        @tip = sth_tip,  @miktar = sth_miktar,  
        @stokkod = sth_stok_kod, @tarih = sth_tarih 
    from inserted 

    select @Counter = COUNT(sth_tip) 
    from STOK_HAREKETLERI  
    where sth_evraktip = 6 
      and sth_tip = @tip 
      and sth_miktar = @miktar 
      and @stokkod = sth_stok_kod 
      and @tarih = sth_tarih   

    if (@counter>=1)  
    begin     
       rollback     
       RAISERROR ('Record already exists', 17, -1) with log 
    end    
END
GO

触发器不会在插入语句上触发,但是如果我删除变量并填充数据并在 SQL Server 上运行它,它运行良好。

有什么建议吗?

如果我将行 (@counter >= 1) 更改为 (@counter >= 0),它会再次开始工作。

【问题讨论】:

  • 触发器不会为每一行执行,它是在语句级别
  • 你能解释一下你的说法吗?
  • 您的触发器有 MAJOR 缺陷,因为您似乎认为它会每行调用一次 - 那是不是 b> 情况。触发器将每个语句触发一次,因此如果您的UPDATE 语句影响25 行,您将触发触发器一次,然后Inserted 和@987654326 @ 每个将包含 25 行。您的代码将选择这 25 行中的哪一行?它是不确定的。您需要重写触发器以考虑到这一点!
  • 这种事情不是最好用唯一的约束来完成吗?
  • @DavidFaber 不,为什么?因为这张表有很多类型的记录,我不想停止,我只想停止这一项。

标签: sql-server triggers insert


【解决方案1】:

如果您插入多行,“已插入”中将有多行,但您只检查最后一行。根据“sth_evraktip = 6”的实际规则(以后是否可以通过更新等完成更多行),进行检查约束可能更容易。

使用插入触发器,这样的事情可能会起作用:

if exists (select 1 from inserted i
where exists(select 1 from STOK_HAREKETLERI S
where S.sth_evraktip = 6
and S.sth_tip = i.sth_tip
and S.sth_miktar = i.sth_miktar
and S.sth_stok_kod = i.sth_stok_kod
and S.sth_tarih = i.sth_tarih
and S.sth_RECno < i.sth_RECno)) begin
    rollback
    RAISERROR ('Record already exists', 17, -1) with log 
 end

如果任何列可以包含 NULL,那么您将不得不添加更多逻辑来处理它。

【讨论】:

  • 我试图只插入一行,但它失败了。
  • 失败是什么意思?您是否收到错误或检查不起作用?
  • 不,它没有给出错误,这是我朋友的问题。
  • 添加了一个应该可以工作的例子,但是 sth_evraktip 和 sth_RECno 值可能会导致它丢失一些东西,并且 NULL 总是需要注意的。
  • 谢谢你的建议,我也试试这个。
【解决方案2】:

如果我跳过变量声明并且将值传递给变量触发器可以完美地工作。在我的情况下为每一行 编辑后的代码发布在下面。

Create TRIGGER [dbo].[STOK_HARKETLERI_Insert]
   ON  [dbo].[STOK_HAREKETLERI]
    FOR INSERT
AS
BEGIN
Declare @counter int

select @counter =  COUNT(sth_tip) from STOK_HAREKETLERI
where sth_evraktip = 6
and sth_tip = (select sth_tip from inserted i)
and sth_miktar =(select sth_miktar from inserted)
and sth_stok_kod =(select sth_stok_kod from inserted)
and sth_tarih = (select sth_tarih from inserted)
and sth_RECno < (select sth_RECno from inserted)

if (@counter>=1)

begin
    rollback
    RAISERROR ('Record already exists', 17, -1) with log
end


END

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-09
    相关资源
    最近更新 更多