Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
tabloda tanımlı triger sadece 1 kez çalışıyor.
#1
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.


Ek Dosyalar Resimler
       
"…De ki: "Hiç bilenlerle bilmeyenler bir olur mu? Şüphesiz, temiz akıl sahipleri öğüt alıp-düşünürler" (Zümer Suresi, 9)
Cevapla
#2
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.
Cevapla
#3
@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. 
Cevapla
#4
@mkysoft @bydelphi bilgilendirme için 
teşekkür ediyorum Allah cc razı olsun sql 
hakkında bilmediğim birşey öğrendiğim
"…De ki: "Hiç bilenlerle bilmeyenler bir olur mu? Şüphesiz, temiz akıl sahipleri öğüt alıp-düşünürler" (Zümer Suresi, 9)
Cevapla
#5
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.
Cevapla
#6
(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ş.
Cevapla
#7
(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.
Cevapla
#8
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
Cevapla
#9
@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)
Cevapla
#10
Trigerlarda çoklu işlemlerde döngü kullanmanız gerekiyor. 


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
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  triger hakkında basit bir soru. Bay_Y 8 935 17-08-2023, Saat: 20:05
Son Yorum: Tuğrul HELVACI
  Triger Update işlemlerinde Image yada nText alanlarına ulaşılabilirmi adelphiforumz 1 1.616 09-04-2021, Saat: 11:32
Son Yorum: mrmarman



Konuyu Okuyanlar: 1 Ziyaretçi