Tüm Platformlar için Hızlı Uygulama Geliştirme --->    Kitabımız...      Delphi

Konuyu Paylaş : facebook gplus twitter

Konuyu Oyla:
  • Derecelendirme: 5/5 - 3 oy
  • 1
  • 2
  • 3
  • 4
  • 5
SQL Server : Trigger hangi kipte çalışıyor
#1
Siz de benim gibi bazı hesaplamaları veritabanına kaydetme sırasında yapmayı sevenlerdenseniz veya böyle bir ihtiyacınız varsa sıklıkla bu işleri Trigger'ler üzerinden halletmeniz gerekir.

SQL Server'de bir Trigger'in hangi modda olduğunu o an için bize söyleyen bir işlev yok. Bunu öğrenebilmek için INSERTED ve DELETED tablolarının dolu olup olmadığına bakmanız ve bir çıkarsama yapmanız gerekir. Bu işi kolaylaştıran bir fonksiyon yazmıştım, sizlerle paylaşmanın faydalı olacağına inanıyorum;

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Uğur PARLAYAN>
-- Create date: <16.12.2014 12:46>
-- Description:  <Trigger'lerin hangi kipte çalıştığını anlamak için kullanılır.>
-- =============================================
--CREATE FUNCTION dbo.fn_triggerkipi
 ALTER FUNCTION dbo.fn_triggerkipi
 ( @InsertedCount  INT = 0 -->  Örnek (SELECT TOP 1 COUNT(*) FROM INSERTED)
 , @DeletedCount   INT = 0 -->  Örnek (SELECT TOP 1 COUNT(*) FROM DELETED)
 )
RETURNS VARCHAR(8)
AS  BEGIN
   RETURN
   CASE
     WHEN @InsertedCount > 0 AND @DeletedCount = 0 THEN 'ekle'      --> INSERT Kipidir, DELETED tablosu boş gelir...
     WHEN @InsertedCount > 0 AND @DeletedCount > 0 THEN 'değiştir'  --> UPDATE Kipidir, Her iki tablo da doludur... DELETED tablosu önceki veriyi, INSERTED ise yeni veriyi tutar...
     WHEN @InsertedCount = 0 AND @DeletedCount > 0 THEN 'sil'       --> DELETE Kipidir, INSERTED tablosu boş gelir...
     ELSE 'yok'                                                     --> Hiçbiri       , Her iki tablo da boştur... (Ki aslında parametre hatalıysa böyle bir durum oluşur)
   END;
END

Kullanımı oldukça basittir ve genel anlamda sık sık trigger'ler ile uğraşıyorsanız bu bahsettiğim adımı basite indirgemenizde size yardımcı olacaktır.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author      : <Uğur PARLAYAN>
-- Create date : <2017-02-20>
-- Description : <...>
-- =============================================
ALTER TRIGGER  [dbo].[TRG_Ajanda]
         ON  [dbo].[Ajanda]
FOR INSERT, DELETE, UPDATE
AS  BEGIN
   
   SET NOCOUNT ON;
   
   DECLARE @TRG_Durum  VARCHAR(8) = dbo.fn_triggerkipi( (SELECT TOP 1 COUNT(*) FROM INSERTED), (SELECT TOP 1 COUNT(*) FROM DELETED) )
   
   IF (@TRG_Durum = 'ekle')
   or (@TRG_Durum = 'değiştir') BEGIN

       UPDATE  X
       SET     X.Taslak = ISNULL(I.Taslak, 0)
       FROM    dbo.Ajanda    as  X      LEFT OUTER
       JOIN    INSERTED      as  I  on  I.Ref = X.Ref
       WHERE   X.Ref in (SELECT DISTINCT Ref FROM INSERTED)
       ;
   END ELSE
   IF (@TRG_Durum = 'sil') BEGIN
       SET NOCOUNT ON; --> bu satırın yerine silme işlemi sırasında bir log tutuyorsanız ilgili kodlarınızı bu noktaya yazabilirsiniz...
   END
END

Görüldüğü gibi 17. satırda (@TRG_Durum) değişkenine hangi modda çalıştığı işleniyor ve devamındaki IF bloğunda da mevcut duruma göre SQL kodlarınızı birbirine karıştırmadan yazabiliyorsunuz.
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla
#2
SQL Sever'da, Tablolarda, Before, After olayları yokmu ?
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla
#3
(03-07-2017, Saat: 12:34)esistem Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlSQL Sever'da, Tablolarda, Before, After olayları yokmu ?

Malesef, SQL Server'da BEFORE ve AFTER gibi (Daha çok MySQL'in sunduğpu türden) tetik mekanizmaları yok. MySQL ve SQL Server'in tetik mantığı birbirinden çok farklıdır. MySQL tek tek tüm insert, update ve delete işlemleri için trigger tanımlamanıza izin verirken SQL Server olaya bir bütün olarak bakar, ve topluca işlemler yapabilmenize imkan tanır.

Belki Before Trigger'e en yakın olan şey INSTEAD OF UPDATE triggerleri olabilir, onunla ilgili bilgiye aşağıdaki linkten erişebilirsiniz. 

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Benzer bir soruyu başkası da sormuş;

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Not: Sorunuzu MySQL geçmişiniz olduğunu varsaydığım için bu yönde cevapladım ( Farklı da olabilir tabi )
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla
#4
SQL Sever ile hiç proje yazmadım, bi kaç kez veri çekmek için kullandım ama dikkatlice hiç incelememiştim öğrendiğim iyi oldu.
Bu arada VCl için sadece Firebird kullanıyorum, MYSQL i de sadece web de kullanıyorum.
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
WWW
Cevapla
#5
Benzer bir işlevselliği ben de aşağıdaki gibi sağlıyorum:

ALTER TRIGGER [dbo].[trg_IO_Cari_Tanimlari_INSERT_UPDATE_DELETE] ON [dbo].[t_Cari_Tanimlari]
INSTEAD OF INSERT,UPDATE,DELETE
AS
  SET NOCOUNT ON;

  DECLARE
    @TriggerType VARCHAR(3),
    @DeleteCount INT,
    @InsertCount INT

  SET @TriggerType = ''

  BEGIN TRY
    SELECT @DeleteCount = COUNT(*) FROM DELETED
  END TRY
  BEGIN CATCH
  END CATCH

  BEGIN TRY
    SELECT @InsertCount = COUNT(*) FROM INSERTED
  END TRY
  BEGIN CATCH
  END CATCH

  SELECT @TriggerType = 
    CASE
      WHEN (ISNULL(@InsertCount, 0) > 0) AND (ISNULL(@DeleteCount, 0) > 0) THEN 'UPD'
      WHEN (ISNULL(@InsertCount, 0) > 0)  THEN 'INS'
      WHEN (ISNULL(@DeleteCount, 0) > 0) THEN 'DEL'
      ELSE ''
    END

  IF @TriggerType = '' 
  BEGIN
    IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION

    RAISERROR('İşlem yapılacak bir kayıt bulunamadı.!', 16, 1)
    RETURN
  END

  ...
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#6
(03-07-2017, Saat: 11:59)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlSiz de benim gibi bazı hesaplamaları veritabanına kaydetme sırasında yapmayı sevenlerdenseniz veya böyle bir ihtiyacınız varsa sıklıkla bu işleri Trigger'ler üzerinden halletmeniz gerekir.

SQL Server'de bir Trigger'in hangi modda olduğunu o an için bize söyleyen bir işlev yok. Bunu öğrenebilmek için INSERTED ve DELETED tablolarının dolu olup olmadığına bakmanız ve bir çıkarsama yapmanız gerekir. Bu işi kolaylaştıran bir fonksiyon yazmıştım, sizlerle paylaşmanın faydalı olacağına inanıyorum;

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <Uğur PARLAYAN>
-- Create date: <16.12.2014 12:46>
-- Description:  <Trigger'lerin hangi kipte çalıştığını anlamak için kullanılır.>
-- =============================================
--CREATE FUNCTION dbo.fn_triggerkipi
 ALTER FUNCTION dbo.fn_triggerkipi
 ( @InsertedCount  INT = 0 -->  Örnek (SELECT TOP 1 COUNT(*) FROM INSERTED)
 , @DeletedCount   INT = 0 -->  Örnek (SELECT TOP 1 COUNT(*) FROM DELETED)
 )
RETURNS VARCHAR(8)
AS  BEGIN
   RETURN
   CASE
     WHEN @InsertedCount > 0 AND @DeletedCount = 0 THEN 'ekle'      --> INSERT Kipidir, DELETED tablosu boş gelir...
     WHEN @InsertedCount > 0 AND @DeletedCount > 0 THEN 'değiştir'  --> UPDATE Kipidir, Her iki tablo da doludur... DELETED tablosu önceki veriyi, INSERTED ise yeni veriyi tutar...
     WHEN @InsertedCount = 0 AND @DeletedCount > 0 THEN 'sil'       --> DELETE Kipidir, INSERTED tablosu boş gelir...
     ELSE 'yok'                                                     --> Hiçbiri       , Her iki tablo da boştur... (Ki aslında parametre hatalıysa böyle bir durum oluşur)
   END;
END

Kullanımı oldukça basittir ve genel anlamda sık sık trigger'ler ile uğraşıyorsanız bu bahsettiğim adımı basite indirgemenizde size yardımcı olacaktır.

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author      : <Uğur PARLAYAN>
-- Create date : <2017-02-20>
-- Description : <...>
-- =============================================
ALTER TRIGGER  [dbo].[TRG_Ajanda]
         ON  [dbo].[Ajanda]
FOR INSERT, DELETE, UPDATE
AS  BEGIN
   
   SET NOCOUNT ON;
   
   DECLARE @TRG_Durum  VARCHAR(8) = dbo.fn_triggerkipi( (SELECT TOP 1 COUNT(*) FROM INSERTED), (SELECT TOP 1 COUNT(*) FROM DELETED) )
   
   IF (@TRG_Durum = 'ekle')
   or (@TRG_Durum = 'değiştir') BEGIN

       UPDATE  X
       SET     X.Taslak = ISNULL(I.Taslak, 0)
       FROM    dbo.Ajanda    as  X      LEFT OUTER
       JOIN    INSERTED      as  I  on  I.Ref = X.Ref
       WHERE   X.Ref in (SELECT DISTINCT Ref FROM INSERTED)
       ;
   END ELSE
   IF (@TRG_Durum = 'sil') BEGIN
       SET NOCOUNT ON; --> bu satırın yerine silme işlemi sırasında bir log tutuyorsanız ilgili kodlarınızı bu noktaya yazabilirsiniz...
   END
END

Görüldüğü gibi 17. satırda (@TRG_Durum) değişkenine hangi modda çalıştığı işleniyor ve devamındaki IF bloğunda da mevcut duruma göre SQL kodlarınızı birbirine karıştırmadan yazabiliyorsunuz.



Merhaba,

Bir tabloyu log olarak tutarken nasıl kullanabiliriz ? Bu örneği.

İyi çalışmalar,
Cevapla
#7
(10-09-2017, Saat: 14:51)denizfatihi Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlMerhaba,

Bir tabloyu log olarak tutarken nasıl kullanabiliriz ? Bu örneği.

İyi çalışmalar,

LOG bilgisini hangi düzeyde tutacağınızı bilmiyorum, eğer mevcut bir kaydı kim ne zaman nerede hangi terminalden değiştirmiş veya oluşturmuş gibi bir bilgi tutmak istiyorsanız aşağıdaki linkte müzakere edilen konuyu incelemenizi tavsiye ederim;

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Bununla birlikte yukarıdaki linkte bahsedilen bilgileri bu makaledeki örnek trigger kodunun 22 ila 26. satırları arasındaki UPDATE bölümüne gömebilirsiniz,
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla
#8
(10-09-2017, Saat: 20:59)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
(10-09-2017, Saat: 14:51)denizfatihi Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlMerhaba,

Bir tabloyu log olarak tutarken nasıl kullanabiliriz ? Bu örneği.

İyi çalışmalar,

LOG bilgisini hangi düzeyde tutacağınızı bilmiyorum, eğer mevcut bir kaydı kim ne zaman nerede hangi terminalden değiştirmiş veya oluşturmuş gibi bir bilgi tutmak istiyorsanız aşağıdaki linkte müzakere edilen konuyu incelemenizi tavsiye ederim;

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Bununla birlikte yukarıdaki linkte bahsedilen bilgileri bu makaledeki örnek trigger kodunun 22 ila 26. satırları arasındaki UPDATE bölümüne gömebilirsiniz,


O kadar detaya gerek yok sadece satır içinde nasıl bir değişiklik yapılmış veya silinmiş mi şeklinde olması yeterli.
Bu arada mssql 2008 kullanıyorum yönlendirdiğiniz sayfada yer alan FUNCTION işlemini oluşturamadım, versiyon farkı ile ilgili bir durum mu var ? 
Şimdiden teşekkür ederim. 

CREATE TABLE [dbo].[TBL_SOZLESME](
 [ID] [int] IDENTITY(1,1) NOT NULL,
[SICIL] [int] NULL,
[TCKIMLIK] [varchar](12) NULL,
[ADI] [varchar](30) NULL,
[SOYADI] [varchar](30) NULL,
[DOGUMTAR] [smalldatetime] NULL,
[BASSIGTAR] [smalldatetime] NULL,
[ISEGIRTAR] [smalldatetime] NULL,
[SOZTAR] [smalldatetime] NULL,
[SOZBITTAR] [smalldatetime] NULL,
[GOREV] [varchar](50) NULL,
[ADRES] [varchar](200) NULL,
[RAPORAOLAN] [varchar](50) NULL,
[SAATUCRETI] [float] NULL,
[TOPLAMSAAT] [float] NULL,
[FIRMA] [int] NULL,
[T1] [float] NULL,
[T2] [float] NULL,
[SOZBITTAR2] [smalldatetime] NULL,
[FIRMA_ADI] [varchar](60) NULL,
[FIRMA_ADRES] [varchar](150) NULL,
CONSTRAINT [PK_SOZLESME] PRIMARY KEY NONCLUSTERED 
(
[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
)
Cevapla
#9
(10-09-2017, Saat: 21:47)denizfatihi Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol
(10-09-2017, Saat: 20:59)uparlayan Adlı Kullanıcıdan Alıntı: Linkleri Görebilmeniz İçin Giriş yap veya Üye OlLOG bilgisini hangi düzeyde tutacağınızı bilmiyorum, eğer mevcut bir kaydı kim ne zaman nerede hangi terminalden değiştirmiş veya oluşturmuş gibi bir bilgi tutmak istiyorsanız aşağıdaki linkte müzakere edilen konuyu incelemenizi tavsiye ederim;

Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol

Bununla birlikte yukarıdaki linkte bahsedilen bilgileri bu makaledeki örnek trigger kodunun 22 ila 26. satırları arasındaki UPDATE bölümüne gömebilirsiniz,


O kadar detaya gerek yok sadece satır içinde nasıl bir değişiklik yapılmış veya silinmiş mi şeklinde olması yeterli.
Bu arada mssql 2008 kullanıyorum yönlendirdiğiniz sayfada yer alan FUNCTION işlemini oluşturamadım, versiyon farkı ile ilgili bir durum mu var ? 
Şimdiden teşekkür ederim. 

CREATE TABLE [dbo].[TBL_SOZLESME](
 [ID] [int] IDENTITY(1,1) NOT NULL,
[SICIL] [int] NULL,
[TCKIMLIK] [varchar](12) NULL,
[ADI] [varchar](30) NULL,
[SOYADI] [varchar](30) NULL,
[DOGUMTAR] [smalldatetime] NULL,
[BASSIGTAR] [smalldatetime] NULL,
[ISEGIRTAR] [smalldatetime] NULL,
[SOZTAR] [smalldatetime] NULL,
[SOZBITTAR] [smalldatetime] NULL,
[GOREV] [varchar](50) NULL,
[ADRES] [varchar](200) NULL,
[RAPORAOLAN] [varchar](50) NULL,
[SAATUCRETI] [float] NULL,
[TOPLAMSAAT] [float] NULL,
[FIRMA] [int] NULL,
[T1] [float] NULL,
[T2] [float] NULL,
[SOZBITTAR2] [smalldatetime] NULL,
[FIRMA_ADI] [varchar](60) NULL,
[FIRMA_ADRES] [varchar](150) NULL,
CONSTRAINT [PK_SOZLESME] PRIMARY KEY NONCLUSTERED 
(
[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
)

FUNCTION'u oluştururken aldığınız hata mesajını paylaşırsanız sorunun nereden kaynaklandığı ile ilgili daha doğru bir çözüm önerebiliriz.

Bunun dışında, "satır içinde nasıl bir değişiklik yapıldığı" veya "silinmiş mi" konularıyla ile ilgili olarak ben sizin yerinizde olsam LOG'lar için ayrı bir tablo oluşturur ve bu bilgileri orada tutardım. Silme, değiştirme gibi fiillerin sonuçlarını trigger düzeyinde takip etmek sizin işinizi uzatır düşüncesindeyim, bu yaklaşım fazladan kod yazmak gibi külfetlere sebep olur, bunun yerine silme, değiştirme, oluşturma gibi işlemlerinizi Delphi uygulamasındaki datasetlerin AfterInsert, AfterEdit, AfterDelete gibi olaylarında LOG tablosuna yazacak şekilde düzenlemenizi  veya Action'ları kullanıyorsanız kullanıyorsanız ilgili silme, değiştirme ve düzenleme actionlarının uygun bir noktasına yine LOG tablosuna yazacak şekilde yama yapmanızı tavsiye ederim.

Tabi, bazı noktalar tercih meselesidir fakat asgari ölçekte bir LOG tablosuna örnek vermek gerekirse, bu aşağı yukarı şöyle bir yapı olabilir;

USE [Taslak]
GO

/****** Object:  Table [dbo].[App_Log]    Script Date: 11.09.2017 00:06:09 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[App_Log](
[Ref] [int] IDENTITY(1,1) NOT NULL,
[Zaman] [datetime] NOT NULL,
[Ekran] [varchar](50) NULL,
[Nesne] [varchar](50) NULL,
[Eylem] [varchar](50) NULL,
[Aciklamalar] [varchar](255) NULL,
[Firma] [int] NULL,
[Donem] [int] NULL,
[Kullanici] [int] NULL,
[Terminal] [int] NULL,
[TerminalAdi] [varchar](128) NULL,
[UygulamaAdi] [varchar](50) NULL,
[Kaynak] [varchar](50) NULL,
[KaynakRef] [int] NULL,
[MacAdres] [varchar](18) NULL,
[LanIP] [varchar](15) NULL,
[WanIP] [varchar](15) NULL,
CONSTRAINT [PK_App_Log] PRIMARY KEY CLUSTERED 
(
[Ref] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[App_Log] ADD  CONSTRAINT [DF_App_Log_Zaman]  DEFAULT (getdate()) FOR [Zaman]
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Sisteme kayıtlı olan bilgisayarlar kastedilmektedir. ' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'App_Log', @level2type=N'COLUMN',@level2name=N'Terminal'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'SQL Server''in tespit ettiği cihaz adıdır (PC ise NETBIOSNAME, cep telefonu ise benzer bir şey gibi düşünün...)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'App_Log', @level2type=N'COLUMN',@level2name=N'TerminalAdi'
GO

Tabi bu log tablosunun triggeri de şu şekilde olabilir;

USE [Taslak]
GO
/****** Object:  Trigger [dbo].[TRG_App_Log]    Script Date: 10.09.2017 23:42:53 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:  <Uğur PARLAYAN>
-- Create date: <2017-08-02-1121>
-- Description: <LOG Sisteminde veritabanı ayağındaki eksik kısımlar bu noktada tamamlanıyor...>
-- =============================================
CREATE   TRIGGER [dbo].[TRG_App_Log]
-- ALTER   TRIGGER [dbo].[TRG_App_Log]
   ON  [dbo].[App_Log]
   FOR INSERT,DELETE,UPDATE
AS  BEGIN
  SET NOCOUNT ON;
DECLARE @TRG_Durum VARCHAR(10) = ''
SET @TRG_Durum = dbo.fn_triggerkipi( (SELECT TOP 1 COUNT(*) FROM INSERTED), (SELECT TOP 1 COUNT(*) FROM DELETED) )
IF (@TRG_Durum = 'ekle')
or (@TRG_Durum = 'değiştir') BEGIN
UPDATE X SET
               X.LanIP         = IIF( (@TRG_Durum = 'ekle'), CAST(CONNECTIONPROPERTY('local_net_address')  as VARCHAR(18)) , D.LanIP )
           ,   X.WanIP         = IIF( (@TRG_Durum = 'ekle'), CAST(CONNECTIONPROPERTY('client_net_address') as VARCHAR(18)) , D.WanIP )
           ,   X.MacAdres      = IIF( (@TRG_Durum = 'ekle'), dbo.fn_FormatMacAdres(p.net_address)                          , D.MacAdres)
           ,   X.TerminalAdi   = IIF( (@TRG_Durum = 'ekle'), LTRIM(RTRIM(p.hostname))                                      , D.TerminalAdi)
           ,   X.UygulamaAdi   = IIF( (@TRG_Durum = 'ekle'), LTRIM(RTRIM(p.program_name))                                  , D.UygulamaAdi)
FROM dbo.App_Log    as X LEFT OUTER
       JOIN    INSERTED as I on I.Ref = X.Ref         LEFT OUTER
       JOIN    DELETED                           as  D   on  D.Ref = X.Ref         LEFT OUTER
       JOIN    sys.sysprocesses                  as  p   on  p.spid = @@SPID
WHERE X.Ref in (SELECT DISTINCT Ref FROM INSERTED)
;
END;
END
GO

Eğer bir kayıtın "en son" kim tarafından üretildiği, düzenlendiği veya silindiği ile ilgili bilgileri tutmak istiyorsanız sizin tablonuzu şu şekilde düzenlemek daha uygun bir yaklaşım olabilir;

CREATE TABLE [dbo].[TBL_SOZLESME]
( [ID] [int] IDENTITY(1,1) NOT NULL
, [SICIL] [int] NULL
, [TCKIMLIK] [varchar](12) NULL
, [ADI] [varchar](30) NULL
, [SOYADI] [varchar](30) NULL
, [DOGUMTAR] [smalldatetime] NULL
, [BASSIGTAR] [smalldatetime] NULL
, [ISEGIRTAR] [smalldatetime] NULL
, [SOZTAR] [smalldatetime] NULL
, [SOZBITTAR] [smalldatetime] NULL
, [GOREV] [varchar](50) NULL
, [ADRES] [varchar](200) NULL
, [RAPORAOLAN] [varchar](50) NULL
, [SAATUCRETI] [float] NULL
, [TOPLAMSAAT] [float] NULL
, [FIRMA] [int] NULL
, [T1] [float] NULL
, [T2] [float] NULL
, [SOZBITTAR2] [smalldatetime] NULL
, [FIRMA_ADI] [varchar](60) NULL
, [FIRMA_ADRES] [varchar](150) NULL

, [_Olusturan] [int] NULL
, [_Degistiren] [int] NULL
, [_Silen] [int] NULL
, [_Olusturma] [datetime] NULL
, [_Degistirme] [datetime] NULL
, [_Silme] [datetime] NULL

, CONSTRAINT [PK_SOZLESME] PRIMARY KEY NONCLUSTERED 
( [ID] ASC )
 WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
)
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla
#10
Tekrar merhaba,

@denizfatihi MsSQL 2008 kullandığınızı belirtmiştiniz, verdiğim örnekteki "IIF" komutları sizin SQL sürümünüzde desteklenmediği için hata verecektir, gözden kaçırdığım bu detay ile ilgili olarak IIF kısımlarını CASE komutunu kullanarak çözebilirsiniz. Örneğin;

,   X.TerminalAdi   = IIF( (@TRG_Durum = 'ekle'), LTRIM(RTRIM(p.hostname)) , D.TerminalAdi)

Şeklindeki kısmı aşağıdaki gibi düzenleyebilirsiniz;

,   X.TerminalAdi   = CASE @TRG_Durum
                           WHEN 'ekle'      THEN LTRIM(RTRIM(p.hostname))
                           WHEN 'değiştir'  THEN D.TerminalAdi     --> Bu satırda mevcut kayıtta bir değişiklik yapıldıysa önceki değeri korumaya alıyoruz
                           ELSE D.TerminalAdi                      --> Bu satırda ekle veya değiştir kipi dışında bir kip yakalanırsa yine mevcut önceki değeri koruyoruz
                       END

Bu şablonu bir önceki posttaki koda uyarlayabilirsiniz.
Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol,Linkleri Görebilmeniz İçin Giriş yap veya Üye Ol / Neyi bilmediğimiz hakkında hiçbir fikrimiz yok (EM)
Cevapla

Konuyu Paylaş : facebook gplus twitter



Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  MS-SQL Server'da tekrar eden (çift, mükerrer) kayıtları tespit etme ve silme. csunguray 6 134 29-01-2018, Saat: 18:29
Son Yorum: adelphiforumz
  Datasnap + Rest Server -> Evrensel Veri Adaptörü - 001 - Sunucu Uygulaması mad85 7 364 17-11-2017, Saat: 22:56
Son Yorum: mad85
  SQL Server : GROUP_CONCAT ve LISTAGG Simülasyonu uparlayan 0 281 02-07-2017, Saat: 13:47
Son Yorum: uparlayan
  SQL Server : Tablolar için parametrik sıralı alan listesi uparlayan 3 347 01-07-2017, Saat: 19:12
Son Yorum: uparlayan



Konuyu Okuyanlar: 1 Ziyaretçi