Hayırlı akşamlar sql trigger ile ilgili bir sorun için uğraşıyorum.
resimde görünen tabloda toplam
14 adet kayıt var.
tablonun triggers de tanımlı kod:
USE [CINAR2022]
GO
/****** Object: Trigger [dbo].[miktar_sil] Script Date: 2.07.2022 20:06:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[miktar_sil] ON [dbo].[StokHareket]
WITH EXECUTE AS CALLER
FOR DELETE
AS
begin
declare @miktar decimal(8,3)
declare @urunid integer
declare @fistur char
declare @silinen_id integer
select @miktar=ST_MIKTAR,@urunid=ST_STOKID,@fistur=ST_FISTURU,@silinen_id=ST_ID from deleted
update stok set STOK_TOP_GRN=STOK_TOP_GRN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY-@miktar where STOK_ID=@urunid and @fistur='G' -- fis eklendi G artır C ise eksilt
update stok set STOK_TOP_CKN=STOK_TOP_CKN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY+@miktar where STOK_ID=@urunid and @fistur='C'
insert into TempDB values(@urunid ,@fistur,@silinen_id,'Test') // TempDB dosyası gecici ekledim kaç kez gelindi bilgisi için.
end
Bu komutla
DELETE FROM StokHareket where ST_IMA_NO=2;
tablodaki toplam 14 kayıt siliniyor hata yok.
14 kayıt silinmesine rağmen trigger sadece 1 kez çalışıyor ve sadece bir stok güncelleniyor.
where karşılaştırmasında hata yok
TempDB sadece 1 kayıt atıyor.
sql management da message aşağıdaki gibi
(0 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(14 row(s) affected)
Konu hakkında yardım bekliyorum.
"…De ki: "Hiç bilenlerle bilmeyenler bir olur mu? Şüphesiz, temiz akıl sahipleri öğüt alıp-düşünürler" (Zümer Suresi, 9)
Silme islemi tek bir transaction icinde yapildigi icin sadece bir kez gelmesi normal. ST_ID yerine deleted tablosunu kullanin. Trigger otomatik olarka deleted isimli bir tablo olusturur kullanabilmeniz icin.
@mkysoft arkadaşımın dediğine aynen katılarak biraz daha detay vereyim.
Sql server silme işlemi komutunuzu bir batch olarak ele aldığı için tek tek silmez ve dolayısıyla trigger tek tek çalışmaz bir sefer toplu çalışır.
bu delete update insert işlemlerinden etkilenen kayıtları sql server o on scopede 2 tabloda tutar deleted ve inserted tabloları.
bu tablonun içinde sizin silmeye çalıştığınız tablonun ve sadece silinecek kayıtların bire bir aynı kopyası olur.
bu tabloyu kullanarak dieğr tablolarınızla joinleyerek from update veya bu tablodan insert yapabilirsiniz.
başka bir detayda şöyle vereyim;
bir silme işleminde deleted tablosu oluşur
yeni bir ekleme işleminde inserted tablosu oluşur
ancak update işleminde updated tablosu oluşmaz.
bunun yerine sql server update edilecek kayıtların önceki hallerini deleted,
yeni yani güncellenecek hallerini inserted tablosunda saklar.
siz update scope anında bu verileri kontrol edip işleyebilirsiniz.
Sorsaydı Bilirdi Sormuyor ki Bilsin. Bilseydi Sorardı Bilmiyor ki Sorsun.
Update veya Delete işlemleri ile alakalı bir triger yazdıysanız toplu update/delete işlemlerini cursor tanımlayarak cursor içinde id ile birlikte satır satır delete / update yaparsanız sorun olmayacaktır.
(02-07-2022, Saat: 20:25)cinarbil Adlı Kullanıcıdan Alıntı: Hayırlı akşamlar sql trigger ile ilgili bir sorun için uğraşıyorum.
resimde görünen tabloda toplam
14 adet kayıt var.
tablonun triggers de tanımlı kod:
USE [CINAR2022]
GO
/****** Object: Trigger [dbo].[miktar_sil] Script Date: 2.07.2022 20:06:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[miktar_sil] ON [dbo].[StokHareket]
WITH EXECUTE AS CALLER
FOR DELETE
AS
begin
declare @miktar decimal(8,3)
declare @urunid integer
declare @fistur char
declare @silinen_id integer
select @miktar=ST_MIKTAR,@urunid=ST_STOKID,@fistur=ST_FISTURU,@silinen_id=ST_ID from deleted
update stok set STOK_TOP_GRN=STOK_TOP_GRN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY-@miktar where STOK_ID=@urunid and @fistur='G' -- fis eklendi G artır C ise eksilt
update stok set STOK_TOP_CKN=STOK_TOP_CKN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY+@miktar where STOK_ID=@urunid and @fistur='C'
insert into TempDB values(@urunid ,@fistur,@silinen_id,'Test') // TempDB dosyası gecici ekledim kaç kez gelindi bilgisi için.
end
Bu komutla
DELETE FROM StokHareket where ST_IMA_NO=2;
tablodaki toplam 14 kayıt siliniyor hata yok.
14 kayıt silinmesine rağmen trigger sadece 1 kez çalışıyor ve sadece bir stok güncelleniyor.
where karşılaştırmasında hata yok
TempDB sadece 1 kayıt atıyor.
sql management da message aşağıdaki gibi
(0 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(14 row(s) affected)
Konu hakkında yardım bekliyorum.
Selamlar,
Deleted tablosu içinde 14 kayıt olabilir. Toplu delete işlemi için tüm kayıtları silip trigger'i bir defa tetikliyordur. Sanırım @yasard de bunu söylemek istemiş.
(06-07-2022, Saat: 16:14)mustafaozpinar Adlı Kullanıcıdan Alıntı:
(02-07-2022, Saat: 20:25)cinarbil Adlı Kullanıcıdan Alıntı: Hayırlı akşamlar sql trigger ile ilgili bir sorun için uğraşıyorum.
resimde görünen tabloda toplam
14 adet kayıt var.
tablonun triggers de tanımlı kod:
USE [CINAR2022]
GO
/****** Object: Trigger [dbo].[miktar_sil] Script Date: 2.07.2022 20:06:38 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[miktar_sil] ON [dbo].[StokHareket]
WITH EXECUTE AS CALLER
FOR DELETE
AS
begin
declare @miktar decimal(8,3)
declare @urunid integer
declare @fistur char
declare @silinen_id integer
select @miktar=ST_MIKTAR,@urunid=ST_STOKID,@fistur=ST_FISTURU,@silinen_id=ST_ID from deleted
update stok set STOK_TOP_GRN=STOK_TOP_GRN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY-@miktar where STOK_ID=@urunid and @fistur='G' -- fis eklendi G artır C ise eksilt
update stok set STOK_TOP_CKN=STOK_TOP_CKN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY+@miktar where STOK_ID=@urunid and @fistur='C'
insert into TempDB values(@urunid ,@fistur,@silinen_id,'Test') // TempDB dosyası gecici ekledim kaç kez gelindi bilgisi için.
end
Bu komutla
DELETE FROM StokHareket where ST_IMA_NO=2;
tablodaki toplam 14 kayıt siliniyor hata yok.
14 kayıt silinmesine rağmen trigger sadece 1 kez çalışıyor ve sadece bir stok güncelleniyor.
where karşılaştırmasında hata yok
TempDB sadece 1 kayıt atıyor.
sql management da message aşağıdaki gibi
(0 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(14 row(s) affected)
Konu hakkında yardım bekliyorum.
Selamlar,
Deleted tablosu içinde 14 kayıt olabilir. Toplu delete işlemi için tüm kayıtları silip trigger'i bir defa tetikliyordur. Sanırım @yasard de bunu söylemek istemiş.
Yazdığımı şimdi okudum anlaşılmamak üzere yazmışım.
İşi özü triger tek seferlik tetiklenir. Bunun işlem gören bütün satırlar için çalışması isteniyor ise bu işlemleri(delete/update) cursor içinde yapmamız gerekir.
SQL Server üzerinde her ne kadar çok kayıt değişse bile trigger tek sefer tetiklenir ve tüm kayıtlar deleted ve/veya inserted tabloları içerisinde bulunur. Mesela yukarıdaki silme işlemini değişkene alıp tek satır olarak çalıştırmak yerine tüm silinen kayıtlar için aşağıdaki şekilde düzenleyebilirsiniz.
update stok set
STOK_TOP_GRN=STOK_TOP_GRN - case when silinen.ST_FISTURU='G' THEN ST_MIKTAR else 0 end,
STOK_TOP_CKN=STOK_TOP_CKN - case when silinen.ST_FISTURU='C' THEN ST_MIKTAR else 0 end
FROM deleted as silinen
WHERE silinen.ST_FISTURU in ('G', 'C') AND stok.ST_STOKID=silinen.ST_STOKID
Bu örnek üzerinden gereksinimlerinize göre kendi genişletmenizi yapabilirsiniz. Kolay gelsin
@sabanakman bey ve diğer yazan tüm arkadaşlara teşekkür ederim Allah c.c razı olsun.
Sql trigers bu şekilde çalıştığını anlamam ve anlayana kadar geçen zaman ve emek beni yordu
buradan öğrendikten sonra biraz kolayına kaçtım. Trigers değiştirmedim.
programda
data_form.stkhrk_oku ('select * FROM StokHareket where ST_IMA_NO='+kf_imalat_no.Text,False);
while not data_form.stkhrk_sorgu.Eof do data_form.stkhrk_sorgu.Delete;
data_form.stkhrk_sorgu.Close;
kodunu ekledim gecici olarak bu şekilde yaptım.
Ama sql ile ilgili birçok şey öğretti bu sorun bana
"…De ki: "Hiç bilenlerle bilmeyenler bir olur mu? Şüphesiz, temiz akıl sahipleri öğüt alıp-düşünürler" (Zümer Suresi, 9)
ALTER TRIGGER [dbo].[miktar_sil] ON [dbo].[StokHareket]
WITH EXECUTE AS CALLER
FOR DELETE
AS
begin
declare @miktar decimal(8,3)
declare @urunid integer
declare @fistur char
declare @silinen_id integer
DECLARE MIKTARSILME CURSOR FOR
select ST_MIKTAR,ST_STOKID,ST_FISTURU,ST_ID from deleted
OPEN MIKTARSILME
FETCH NEXT FROM MIKTARSILME INTO @miktar,@urunid,@fistur,@silinen_id
WHILE @@FETCH_STATUS =0
BEGIN
update stok set STOK_TOP_GRN=STOK_TOP_GRN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY-@miktar where STOK_ID=@urunid and @fistur='G' -- fis eklendi G artır C ise eksilt
update stok set STOK_TOP_CKN=STOK_TOP_CKN-@miktar,STOK_TOP_BKY=STOK_TOP_BKY+@miktar where STOK_ID=@urunid and @fistur='C'
insert into TempDB values(@urunid ,@fistur,@silinen_id,'Test') // TempDB dosyası gecici ekledim kaç kez gelindi bilgisi için.
FETCH NEXT FROM MIKTARSILME INTO @miktar,@urunid,@fistur,@silinen_id
END
CLOSE MIKTARSILME
DEALLOCATE MIKTARSILME
end