Veritabanında bulunan bazı tablolarımda logging yapmam gerekiyor. Örnek vermek gerekirse fiyat diye bir kolonum var bu fiyat kolonu değiştirilirse ne zaman değişti?Eski değeri neydi ?Yeni değeri ne? bu tür bilgiler ve eğer tablodan bir satır silinirse ne zaman silindi gibi bilgileri nasıl görebiliriz..
MS SQL TRACKING işlemi var bunununla sanırım belli bir güne kadar değişiklikleri takip edebiliyoruz..
Bu konuda googlada araştırma yapınca bu kavramı buldum..
Örnek bir tabloda logging işlemi gösteren bir çalışmayı bura da paylaşabilirseniz sevirinirim.
Yaptığım araştırma sonucu internette bulabildiğim en iyi örnek bu
http://weblogs.asp.net/jongalloway/addi ... r-database
Fakat bu örnek tablonun benzerini oluşturuyor bir field bile değişse kocaman bir satır şeklinde log tablosuna tüm field leri yazıyor.
İstediğim şey sadece değişen tablo ve ve değişen field değerlerini görmek..
Kısacası bu konuyla ilgili paylaşım yapabilirseniz sevinirim.
Sitedeki bununla ilgili konuları inceledim.Fakat istediğim gibi bir çözüm göremedim.
MS SQL veritabanında logging naısl yapılır.
- softdestek
- Üye
- Mesajlar: 155
- Kayıt: 17 Eyl 2010 03:53
Re: MS SQL veritabanında logging naısl yapılır.
Merhaba.
Ben olsam nasıl yapardım,
(1) bir LOG tablosu create ederdim.
(2) bu tabloda ( hepsi string olacak şekilde ) aşağıdaki FIELD tanımlamalarını yapardım.
1 TabloAdi, 2 FieldAdi, 3 DegisiklikTipi, 4 EskiDeger, 5 YeniDeger, 6 DegisiklikTar, 7 DegistirenKullanici
(3a) Sadece kullanıcı tarafından değişiklik yapılıyor da yapılan değişiklik Trigger'lar ile başka tabloara etki etmiyorsa !!!
. .* - Logla( ) isminde yukarıdaki FIELD tiplerine ilişkin içeriği koyup INSERT edecek (sadece INSERT veya SELECT INTO gerekiyor zaten) procedure hazırladım.
. .* - Kullanıcının KAYDET veya GÜNCELLE butonunun altına bu Logla() procedure'ünü koyar işini yapmasını sağlardım.
(3b) Kullanıcı tarafından değişiklik yapılıyor iken üstüne üstlük bir de bu yapılan değişiklik Trigger'lar ile başka tabloara etki ediyorsa !!!
. .* - Yukarıdaki logla kısmı yeterli ise (yani trigger ile tetiklenen yerlerin eski değerleri gereksiz ise) aynı şekilde yapardım.
. .* - TRIGGER eski değerlerini de logla kısmında kullanmak üzere önce bir değişken grubuna kayıt öncesi yedekler ( bir type tanımı gruplamak için idealdir ) POST sonrası da bunların yine parametre olarak geçeceğimiz Logla procedure üzerinden kayıt altına alınmasını sağlardım.
Şimdilik bu kadar, gelişmeler için konuşulabilir.
Ben olsam nasıl yapardım,
(1) bir LOG tablosu create ederdim.
(2) bu tabloda ( hepsi string olacak şekilde ) aşağıdaki FIELD tanımlamalarını yapardım.
1 TabloAdi, 2 FieldAdi, 3 DegisiklikTipi, 4 EskiDeger, 5 YeniDeger, 6 DegisiklikTar, 7 DegistirenKullanici
(3a) Sadece kullanıcı tarafından değişiklik yapılıyor da yapılan değişiklik Trigger'lar ile başka tabloara etki etmiyorsa !!!
. .* - Logla( ) isminde yukarıdaki FIELD tiplerine ilişkin içeriği koyup INSERT edecek (sadece INSERT veya SELECT INTO gerekiyor zaten) procedure hazırladım.
. .* - Kullanıcının KAYDET veya GÜNCELLE butonunun altına bu Logla() procedure'ünü koyar işini yapmasını sağlardım.
(3b) Kullanıcı tarafından değişiklik yapılıyor iken üstüne üstlük bir de bu yapılan değişiklik Trigger'lar ile başka tabloara etki ediyorsa !!!
. .* - Yukarıdaki logla kısmı yeterli ise (yani trigger ile tetiklenen yerlerin eski değerleri gereksiz ise) aynı şekilde yapardım.
. .* - TRIGGER eski değerlerini de logla kısmında kullanmak üzere önce bir değişken grubuna kayıt öncesi yedekler ( bir type tanımı gruplamak için idealdir ) POST sonrası da bunların yine parametre olarak geçeceğimiz Logla procedure üzerinden kayıt altına alınmasını sağlardım.
Şimdilik bu kadar, gelişmeler için konuşulabilir.
- softdestek
- Üye
- Mesajlar: 155
- Kayıt: 17 Eyl 2010 03:53
Re: MS SQL veritabanında logging naısl yapılır.
Ben örnek olması açısından aşağıdaki gibi bir örnek birt table guest oluşturdum.
Bu table için de aşağıdaki gibi bir triger oluşturdum...
Bu triger guest tablosunda olan tüm değişiklikleri AutoAudit tablosuna xml olarak yazıyor..
<row GUEST_ID="5" GUEST_NAME="GÖKHAN" GUEST_SURNAME="ÇEVİK" />
<row GUEST_ID="5" GUEST_NAME="GÖKHAN" GUEST_SURNAME="ÇEVİK21" />
Ben daha önce firebird veritabanı kullanırken aşağıdaki gibi log tutmuştum.Fakat kayıt sayısı artacağı için logu fieldler tanımlayarak tutmak yerine
xml olarak tutmak daha mı mantıklı arkadaşlar ne dersiniz?
Kod: Tümünü seç
USE [DENEME]
GO
/****** Object: Table [dbo].[GUESTS] Script Date: 04.07.2015 17:15:51 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[GUESTS](
[GUEST_ID] [int] IDENTITY(1,1) NOT NULL,
[GUEST_NAME] [varchar](50) NULL,
[GUEST_SURNAME] [varchar](50) NULL,
[ADRESS] [varchar](100) NULL,
[CITY] [varchar](50) NULL,
[CITY_CODE] [varchar](10) NULL,
[COUNTRY] [varchar](50) NULL,
[STATUS] [varchar](20) NULL,
[COMMENT] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED
(
[GUEST_ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
Kod: Tümünü seç
USE [DENEME]
GO
/****** Object: Trigger [dbo].[iudt_AutoAuditChanges] Script Date: 04.07.2015 17:17:15 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[iudt_AutoAuditChanges]
ON [dbo].[GUESTS]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
SET NOCOUNT ON;
Declare @v_AuditID bigint
IF OBJECT_ID('dbo.AutoAudit','U') IS NULL BEGIN
CREATE TABLE [dbo].[AutoAudit]
( [AuditID] bigint identity,
[AuditDate] DateTime,
[AuditUserName] varchar(128),
[TableName] varchar(128) NULL,
[OldContent] XML NULL,
[NewContent] XML NULL
)
ALTER TABLE dbo.AutoAudit ADD CONSTRAINT
PK_AutoAudit PRIMARY KEY CLUSTERED
(
[AuditID]
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX [idx_AutoAudit_TableName_AuditDate] ON [dbo].[AutoAudit]
( [TableName] ASC,
[AuditDate] ASC
)WITH (STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END
Select * Into #AuditDeleted from deleted
Select * Into #AuditInserted from inserted
While (Select COUNT(*) from #AuditDeleted) > 0 OR (Select COUNT(*) from #AuditInserted) > 0
Begin
INSERT INTO [dbo].[AutoAudit]
( [AuditDate], [AuditUserName], [TableName], [OldContent], [NewContent])
SELECT
GETDATE(),
SUSER_NAME(),
[TableName]=object_name([parent_obj]),
[OldContent]=CAST((SELECT TOP 1 * FROM #AuditDeleted D FOR XML RAW) AS xml),
[NewContent]=CAST((SELECT TOP 1 * FROM #AuditInserted I FOR XML RAW) AS xml)
FROM sysobjects
WHERE
[xtype] = 'tr'
and [name] = OBJECT_NAME(@@PROCID)
Set @v_AuditID = SCOPE_IDENTITY()
Delete from AutoAudit
Where AuditID = @v_AuditID
AND Convert(varchar(max),oldContent) = Convert(varchar(max),NewContent)
Delete top(1) from #AuditDeleted
Delete top(1) from #AuditInserted
End
END
Bu triger guest tablosunda olan tüm değişiklikleri AutoAudit tablosuna xml olarak yazıyor..
<row GUEST_ID="5" GUEST_NAME="GÖKHAN" GUEST_SURNAME="ÇEVİK" />
<row GUEST_ID="5" GUEST_NAME="GÖKHAN" GUEST_SURNAME="ÇEVİK21" />
Ben daha önce firebird veritabanı kullanırken aşağıdaki gibi log tutmuştum.Fakat kayıt sayısı artacağı için logu fieldler tanımlayarak tutmak yerine
xml olarak tutmak daha mı mantıklı arkadaşlar ne dersiniz?