2016-03-29 17 views
0

Verileri CHECKINOUT tablosuna ekledikten sonra verileri başka bir tabloya eklemek için bu tetiği yazdım.SQL Server: Başka bir Tablo Güncelleştirmesi için Trigger Ekledikten Sonra

Ancak, Att_process tablosuna veri eklemiyor. SQL Server'da hiçbir hata görünmüyor. Bu problemi çözmeme yardım edebilir misin?

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE TRIGGER [dbo].[trgAfterInsert] ON [dbo].[CHECKINOUT] 
AFTER INSERT 
AS 
    DECLARE @uid INT; 
    DECLARE @checkin DATETIME; 

    SELECT @uid = i.USERID 
    FROM [CHECKINOUT] i; 

    SELECT @checkin = i.CHECKTIME 
    FROM [CHECKINOUT] i; 

    IF(DATEPART(HOUR, @checkin) < 12) 
    BEGIN 
     INSERT INTO Att_process (USERID, checkin_time) 
     VALUES (@uid, @checkin); 
    END; 
    ELSE 
    BEGIN 
     INSERT INTO Att_process (USERID, checkout_time) 
     VALUES (@uid, @checkin); 
    END; 
+0

'SELECT @uid = i.USERID Eklenen i; SELECT @checkin = i.CHECKTIME Eklenen i; – artm

+2

@artm: bu, gitmenin yolu değil! ** 'Eklenen' ***, birden çok satır içerecek - bunlardan hangisi burayı mı seçiyorsun ?? Tetikleyiciyi, 'Eklenenler' içinde ** doğru sırayla ** işlemek için yazmanız gerekiyor! –

+0

@marc_s - ha ha iyi dedi! Bu kötü bir düzeltme oldu –

cevap

2

iki ana sorunlar: Eğer

  • tetiği varsayıyoruz, yeni eklenen satırları içerir Inserted sözde masaya bakmıyoruz satır başına bir kere denir

    • - değil, ifadesi ve Inserted pseudo tabloları için bir kez tetiklenir. Birden çok satır içeriyor - ve Bunun yerine bu kodu deneyin

    ile uğraşmak gerekir: Son ayıklamak verileri eklenen etmek 'eklenen' sihirli tablosu kullanılarak olmadığı için

    CREATE TRIGGER [dbo].[trgAfterInsert] ON [dbo].[CHECKINOUT] 
    AFTER INSERT 
    AS 
        -- grab all the rows from the "Inserted" pseudo table 
        -- and insert into the "checkin_time" column, if the value 
        -- of the HOUR is less than 12 
        INSERT INTO Att_process (USERID, checkin_time) 
         SELECT 
          i.USERID, i.CHECKTIME 
         FROM 
          Inserted i 
         WHERE 
          DATEPART(HOUR, i.CHECKTIME) < 12 
    
        -- grab all other rows (HOUR is greater than or equal to 12) 
        -- and insert into the "checkout_time" column 
        INSERT INTO Att_process (USERID, checkout_time) 
         SELECT 
          i.USERID, i.CHECKTIME 
         FROM 
          Inserted i 
         WHERE 
          DATEPART(HOUR, i.CHECKTIME) >= 12 
    
  • -1

    , bu deneyin.

    DECLARE @uid INT; 
    DECLARE @checkin DATETIME; 
    
    SELECT @uid = USERID FROM inserted 
    
    SELECT @checkin = CHECKTIME FROM inserted 
    
    +0

    ** Bu gitmek için yol değil! ** 'Inserted' 'INSERT 'birden fazla öğe eklediyse birden fazla satır içerecektir - hangisini burada seçiyorsun ?? Tetikleyiciyi, 'Eklenenler' içinde ** birden fazla satırı ** doğru şekilde işlemek için yazmanız gerekiyor! –

    +0

    Mysql'de aynı şeyi nasıl yapabileceğimi söyler misiniz? Ayrıca mysql aynı tabloya sahip olduğumdan da –

    1

    Birçok SQL geliştiricileri SQL Server tetikleyiciler ile aynı hatayı yaşamış yaptı. Tabloda çoklu insert ifadeleri yürütüldüğünde davayı kaçırdınız. Tetikleyiciler, her satır için değil, SQL deyimi için yalnızca bir kez yürütülür. Bu nedenle, tetikleyicideki kod, SQL ifadesinden etkilenen tüm satırların tüm görevlerini karşılayabilmelidir.

    Aşağıda, tetik kodunuzu nasıl değiştirebileceğiniz bir örnek verilmiştir.

    ALTER TRIGGER [dbo].[trgAfterInsert] ON [dbo].[CHECKINOUT] 
    AFTER INSERT 
    AS 
    
    INSERT INTO Att_process (USERID, checkin_time, checkout_time) 
    select 
        USERID, 
        case when DATEPART(HOUR, CHECKTIME) < 12 then CHECKTIME else null end, 
        case when DATEPART(HOUR, CHECKTIME) < 12 then null else CHECKTIME end 
    FROM inserted 
    

    istikrarlı sonuçlar elde etmek için, tetikleme kodları içinde mevcuttur Eklenen ve silinmiş iç tablolar kullanın.

    Ayrıca, Silinmiş ve Eklenen tabloların nasıl kullanıldığıyla ilgili örneği SQL Trigger to log changes'dan da kontrol edebilirsiniz.

    Bunu size yardımcı olur umarım

    ,

    Son bir not, aynı anda SQL Output clause to insert data into two tables kullanabilirsiniz eğer. Ancak tabiki tetikleyiciler tabanda çalışır, böylece insert deyiminin yürütüldüğü yerde tetikleyiciler çalışır. Output cümleciğini kullanırsanız, bu tabloya veri ekleyen tek SQL ifadesinin, iki tablo arasındaki tutarlılığı korumak için olacağını garanti etmelisiniz.

    +0

    Merhaba Eralper, Mysql'de aynı şeyi nasıl yapacağımı söyler misiniz? –

    İlgili konular