PDA

View Full Version : چطور Log همه کارهای انجام شده بانک شامل :پاک کردن رکورد و...



ali_abbasi22145
چهارشنبه 18 مرداد 1385, 09:20 صبح
سلام
چطور Log همه کارهای انجام شده بانک شامل :پاک کردن رکورد و تغییر رکورد و ... را داشته باشم.
من فکر می کنم SQL SERVER2000 خودش اینکار را باید انجام دهد اگر هست کجاست و انرا چگونه باز کنم و ببینم؟

majid_afra222
چهارشنبه 18 مرداد 1385, 09:29 صبح
سلام
برای Log کردن همه کارها باید تریگرهای مورد نیاز رو بنویسید که همه تریگرها اطلاعات رو در یه جدول log بریزن.
من یه پروسیجر قرار داده بودم که با اون می تونستید تمام تریگرهای مورد نیاز برای log کردن رو ایجاد کنید، موقعی که برای فوروم مشکل پیش اومد حذف شد.
اگه وقت شد امروز دوباره مینویسم و ارسال می کنم.

majid_afra222
چهارشنبه 18 مرداد 1385, 19:30 عصر
سلام
ایجاد یک جدول برای Log کلیه تغییرات اعمال شده در جداول :
1- اول یک جدول جدید می سازیم :



CREATE TABLE [LogTable] (
[LOG_ID] [bigint] IDENTITY (1, 1) NOT NULL ,
[LOG_Table] [varchar] (80) NOT NULL , --نام جدول
[LOG_Condition] [varchar] (2000) NULL , --شرط برای تغییر - فقط روی کلید اصلی
[LOG_ConditionD] [varchar] (2000) NULL , --شرط برای حذف
[LOG_Action] [char] (1) NOT NULL , --I(Insert), D(Delete), U(Update)
[LOG_Date] [datetime] NOT NULL DEFAULT (getdate()), --تاریخ
[LOG_User] [varchar] (50) DEFAULT (user_name()), --نام کاربر تغییر دهنده
[LOG_Application] [varchar] (100) DEFAULT (app_name() NULL) --نام برنامه کاربردی تغییر دهنده
)
GO



بعد نوشتن رویه ای که تریگرهای مورد نیاز برای جداول رو ایجاد کنه :



CREATE Procedure usp_GenerateTrigger
@TableName sysname
AS
BEGIN
DECLARE @Body_G nvarchar(1000), @Body_I nvarchar(4000)
, @Body_U nvarchar(4000), @Body_D nvarchar(4000)
DECLARE @PreCond nvarchar(200), @EquCond nVarchar(1000), @InEquCond nvarchar(1000)
DECLARE @Cond_U nvarchar(1000), @Cond_D nvarchar(1000), @Keys nvarchar(900)
DECLARE @Table sysname, @Schema sysname
DECLARE @Column sysname, @DataType Sysname, @IsIdentity bit
SELECT @Table =PARSENAME(@TableName,1)
, @Schema=ISNULL(PARSENAME(@TableName, 2), CURRENT_USER), @IsIdentity=0

SELECT @Body_G='IF EXISTS (SELECT * FROM SysObjects '+char(13)
+ ' WHERE Type = ''TR'' AND id = Object_id('''+@Schema+'.insTR_Audit_'+ @Table+''')) '+char(13)
+ ' Drop Trigger '+@Schema+'.insTR_Audit_'+@Table+char(13)
+ ' IF EXISTS (SELECT * FROM SysObjects '+char(13)
+ ' WHERE Type = ''TR'' AND id = Object_id('''+@Schema+'.updelTR_Audit_' + @Table+''')) '+char(13)
+ ' Drop Trigger '+@Schema+'.updelTR_Audit_'+@Table+char(13)
+ ' IF EXISTS (SELECT * FROM SysObjects '+char(13)
+ ' WHERE Type = ''TR'' AND id = Object_id('''+@Schema+'.delTR_Audit_' + @Table + ''')) '+char(13)
+ ' Drop Trigger '+@Schema+'.delTR_Audit_'+@Table+char(13)

Select @Body_I ='', @Body_U ='', @Body_D ='',
@EquCOnd ='', @InEquCond ='', @PreCond='',
@Cond_U='', @Cond_D ='', @Keys =''

select @Body_I ='Create Trigger insTR_Audit_'+@Table +' ON '+ @TableName +'
For Insert
As
', @Body_U='Create Trigger updelTR_Audit_'+@Table +' ON '+@TableName+ '
For Update
As
', @Body_d='Create Trigger delTR_Audit_'+@Table+' ON '+@TableName+'
For Delete
As
'

Select @Keys= @Keys +', ['+ COL_Name(Object_ID(@TableName), k.COLID)+']'
from sysIndexKeys k, sysindexes I
Where i.id=object_ID(@TableName) and
i.id = k.id and i.indid=k.indid and
i.status & 0x800 =0x800
order by keyno
--Select @keys
IF LEN(@Keys)>1
select @Keys = SUBSTRING(@Keys, 3, LEN(@Keys)-2)
ELSE
BEGIN
PRINT 'No Primary Keys are available to handle the operation'
RETURN
END

IF CharIndex(', [', @Keys, 2)=0 --there is only one field now check whether it is identity
BEGIN
IF Exists(Select * from syscolumns where name =Substring(@Keys,2, LEn(@Keys)-2) and autoval is not null)
Set @IsIdentity=1
END


Declare FieldList Cursor FOR
Select COLUMN_NAME, DATA_TYPE from Information_Schema.Columns Where TABLE_Name =@Table and TABLE_SCHEMA=@Schema and Data_Type <> 'TimeStamp'
Open FieldList
FETCH NEXT FROM FieldList INTO @Column, @DataType
WHILE @@FETCH_STATUS=0
BEGIN

IF CHARINDEX(''+@Column+'', @Keys)>0
SELECT @Cond_U =@Cond_U+ '+'' AND ' +@Column +' = ''+'+
CASE
WHEN @DataType in ('Smalldatetime', 'DateTime') THEN '
''''''''+ Convert(Varchar(30), I.'+ @Column +', 113)+''''''''
'
WHEN @DataType in ('bigint','bit','BINARY', 'varbinary', 'int', 'smallint', 'tinyint', 'real', 'decimal', 'float', 'money', 'numeric') THEN
' Convert(Varchar(35), I.'+ @Column +')
'
ELSE
' ''''''''+I.'+ @Column + '+''''''''
'
END,
@EquCond = @EquCond+ ' AND I.'+ @Column +' = D.'+@Column,
@InEquCond = @InEquCond+ ' AND I.'+ @Column +' <> D.'+@Column,
@PreCond = @preCond+' AND Update('+ @Column+')',
@Cond_d =@Cond_d+ '+'' AND ' +@Column +' = ''+'+
CASE
WHEN @DataType in ('Smalldatetime', 'DateTime') THEN '
''''''''+ Convert(Varchar(30), D.'+ @Column +', 113)+''''''''
'
WHEN @DataType in ('bigint','bit','BINARY', 'varbinary', 'int', 'smallint', 'tinyint', 'real', 'decimal', 'float', 'money', 'numeric') THEN
' Convert(Varchar(35), D.'+ @Column +')
'
ELSE
' ''''''''+D.'+ @Column + '+''''''''
'
END
FETCH NEXT FROM FieldList INTO @Column, @DataType

END
CLOSE FieldList

deallocate FieldList
IF LEN(@Cond_D)>7
SELECT @Cond_D = ''''+SUBSTRING(@Cond_D, 8, LEN(@Cond_D )-7)
IF LEN(@Cond_U)>7
SELECT @Cond_U = ''''+SUBSTRING(@Cond_U, 8, LEN(@Cond_U )-7)
IF LEN(@PreCond)>5
SELECT @PreCond= 'IF '+ SUBSTRING(@PreCond, 6, LEN(@PreCond)-5)
IF LEN(@EquCond)>5
SELECT @EquCond= ' WHERE '+ SUBSTRING(@EquCond, 6, LEN(@EquCond)-5)
IF LEN(@InEquCond)>5
SELECT @InEquCond= 'WHERE '+ SUBSTRING(@InEquCond, 6, LEN(@InEquCond)-5)


select @Body_I = @Body_I + 'IF EXISTS (Select * from Inserted)
Insert into LogTable (LOG_Table, LOG_Condition, LOG_Action)
Select '''+@Table+''', '+@Cond_U+',''I'' from Inserted I
'
IF @IsIdentity=0
SELECT @Body_U =@Body_U + 'IF EXISTS (Select * from Inserted)
'+@PreCond +'
Insert into LogTable (LOG_Table, LOG_Condition, LOG_ConditionD, LOG_Action)
Select '''+@Table+''', '+@Cond_U+','+@Cond_D+',''U'' from Inserted I, Deleted D
'+@InEquCond+'
ELSE
Insert into LogTable (LOG_Table, LOG_Condition, LOG_ConditionD, LOG_Action)
Select '''+@Table+''', '+@Cond_U+','+@Cond_D+',''U'' from Inserted I, Deleted D
'+@EquCond
Else
SELECT @Body_U =@Body_U + 'Insert into LogTable (LOG_Table, LOG_Condition, LOG_ConditionD, LOG_Action)
Select '''+@Table+''', '+@Cond_U+','+@Cond_D+',''U'' from Inserted I, Deleted D
'+@EquCond

Select @Body_D = @Body_D+'IF EXISTS (Select * from Deleted)
Insert into LogTable (LOG_Table, LOG_ConditionD, LOG_Action)
Select '''+@Table+''', '+@Cond_D+',''D'' from Deleted D
'
Execute sp_ExecuteSQL @Body_G
Execute sp_ExecuteSQL @Body_I
Execute sp_ExecuteSQL @Body_U
Execute sp_ExecuteSQL @Body_D
END


بعد رویه رو با نام یک جدول فراخوانی می کنید.


EXEC usp_GenerateTrigger 'stores'

sm
جمعه 17 شهریور 1385, 13:18 عصر
مجید جان خیلی برنامه جالبی بود
یه سوال ...
برای جداولی که 2 کلید اصلی دارند چیکار باید کرد ؟ ممنون میشم متنش رو برام بزاری

majid_afra222
شنبه 18 شهریور 1385, 08:25 صبح
سلام
شرمنده خیلی سرم شلوغه، برای همین نمی تونم الان تغییرش بدم.
تغییر هم کار زیادی نداره، یه امتان کن اگه نشد چشم.
--------------------
سلام
شرمنده خیلی سرم شلوغه، برای همین نمی تونم الان تغییرش بدم.
تغییر هم کار زیادی نداره، یه امتحان کن اگه نشد چشم.

sm
یک شنبه 19 شهریور 1385, 19:38 عصر
ممنون مجید آقا... من قبلا میخواستم تغییرش بدم ولی به نتیجه ای نرسیدم
ممنون میشم تغییرش بدین

sm
چهارشنبه 22 شهریور 1385, 20:09 عصر
ممنون راهش و پیدا کردم :
set @keys=''
declare @s nvarchar(900)

DECLARE E CURSOR FOR
Select ', ['+ COL_Name(Object_ID(@TableName), k.COLID)+']'
from sysIndexKeys k, sysindexes I
Where i.id=object_ID(@TableName) and
i.id = k.id and i.indid=k.indid and
i.status & 0x800 =0x800
order by keyno

OPEN E
FETCH NEXT FROM E INTO @s
WHILE @@FETCH_STATUS = 0
BEGIN

set @keys=ltrim(rtrim(@keys))+ltrim(rtrim(@s))

FETCH NEXT FROM E INTO @s
END
CLOSE E
deallocate E

بازم از مطلب خوبتون ممنون

majid_afra222
چهارشنبه 22 شهریور 1385, 21:56 عصر
سلام
ممنون که جواب رو هم ارسال کردی

sayyarpoor
یک شنبه 07 آبان 1385, 11:55 صبح
اگر Recovery Model بانک رو Full قرار بدید خود MSSQl تمام ترانزاکشن ها رو در فایل Log
می نویسد و می شه تا یک نقطه زمانی مشخص اطلاعات Log را Restore کرد البته محتویات این فایل Log رو نمی شه دید فقط برای Restore کردن استفاده می شود

hmm
یک شنبه 07 آبان 1385, 14:12 عصر
چه ربطی داره؟
اون برای restore ه ولی سوال چیز دیگه ایه

ama55555
دوشنبه 08 آبان 1385, 10:03 صبح
با سلام و تشکر از sp تون

ولی من وقتی اجرا می کنم این پیغام را می ده



Server: Msg 2715, Level 16, State 3, Procedure usp_GenerateTrigger, Line 0
Column or parameter #-15: Cannot find data type Sysname.
Parameter '@DataType' has an invalid data type.

ali_abbasi22145
جمعه 21 اردیبهشت 1386, 09:12 صبح
اگر Recovery Model بانک رو Full قرار بدید خود MSSQl تمام ترانزاکشن ها رو در فایل Log
می نویسد و می شه تا یک نقطه زمانی مشخص اطلاعات Log را Restore کرد البته محتویات این فایل Log رو نمی شه دید فقط برای Restore کردن استفاده می شود

سلام
می شه کاملتر در مورد چیزی که گفتید توضیح بدهید و به چه کار می آید؟

AminSobati
جمعه 21 اردیبهشت 1386, 22:33 عصر
برای زمانی مناسبه که شما دقیقا زمان بروز مشکل در دیتابیس (مثلا ویرایش نابجا یا ...) رو میدونین و مایلید از نظر زمانی دیتابیس رو به یک دقیقه قبل از لحظه بروز خطا برگردونین. اصطلاحا بهش Point in time recovery گفته میشه.

ali_abbasi22145
شنبه 22 اردیبهشت 1386, 21:17 عصر
سلام
اگر می شود آموزش برگداندن بانک از زمانی دیتابیس رو به یک دقیقه قبل از لحظه بروز خطا برگردونینم را بگویید.

AminSobati
یک شنبه 23 اردیبهشت 1386, 23:36 عصر
دوست عزیزم Forum محلی برای رفعه اشکاله. شما باید آموزش رو در جای دیگه بدست بیارین و سوالات و اشکالاتتون رو اینجا پست کنین

ali643
چهارشنبه 13 تیر 1386, 13:33 عصر
IF LEN(@Cond_D)>7
SELECT @Cond_D = ''''+SUBSTRING(@Cond_D, 8, LEN(@Cond_D )-7)
IF LEN(@Cond_U)>7
SELECT @Cond_U = ''''+SUBSTRING(@Cond_U, 8, LEN(@Cond_U )-7)
IF LEN(@PreCond)>5
SELECT @PreCond= 'IF '+ SUBSTRING(@PreCond, 6, LEN(@PreCond)-5)
IF LEN(@EquCond)>5
SELECT @EquCond= ' WHERE '+ SUBSTRING(@EquCond, 6, LEN(@EquCond)-5)
IF LEN(@InEquCond)>5
SELECT @InEquCond= 'WHERE '+ SUBSTRING(@InEquCond, 6, LEN(@InEquCond)-5)




دوستان می تونند توضیحی در مورد این قسمت بدهند؟

مرسی

nasr
چهارشنبه 23 آبان 1386, 11:54 صبح
-----------------------------------------

nasr
چهارشنبه 23 آبان 1386, 13:20 عصر
-----------------------------------