PDA

View Full Version : سوال: log از نرم افزار



zman123456
شنبه 18 مهر 1388, 19:30 عصر
با سلام
من در حال طراحی قابلیت log گیری از عملکرد کاربران در سیستم هستم.
فیلدهایی که در جدول log قرار دادم اینهاست:
usercode-ActionCode-LogDate-RecordID-IP-WindowsUser-QueryText-LogTime
بعضی ها که مشحصه چی هستن.
ActionCode مربوط میشه به هر دکمه در فرم.یک دکمه در کل نرم افزار یک ActionCode به خصوص داره.یعنی unique هست.
recordID فیلد Identity هر جدولی هست که داره در آن اطلاعات درج یا ویرایش یا حذف میشه.
حالا مشکل من در به دست آوردن RecordID در هنگام Insert هست.از گرفتن max(Identity)+1 نمی خواهم استفاده کنم.به دلایل تخصصی که میدونید.
نرم افزار تحت شبکه است.بانک sql 2000.دلفی 7.

merced
یک شنبه 19 مهر 1388, 06:09 صبح
شما از يه SP استفاده كنيد. كه بعد از Insert دستور Select(Max) اجرا و يه مقدار برگردونه
اين SP رو سمت SQL Server بنويس و درون يه تراكنش قرار بده. تا مطمئن شي مقدار درستي بر مي گردونه

zman123456
یک شنبه 19 مهر 1388, 14:18 عصر
شما از يه SP استفاده كنيد. كه بعد از Insert دستور Select(Max) اجرا و يه مقدار برگردونه
اين SP رو سمت SQL Server بنويس و درون يه تراكنش قرار بده. تا مطمئن شي مقدار درستي بر مي گردونه
سلام
خوب اين يعني اينكه من SP‌رو با Trigger صدا بزنم يا اينكه دستي از توي برنامه؟
منظورتون از اينكه "درون يه تراكنش قرار بده" يعني چي؟
چطور ميشه مطمئن شد كه مقدار درستي بر ميگردونه؟اگه ميشه در پاسخ سوال بالا تشريح نماييد؟
البته من بگم كه اين log رو دارم روي حداقل 10 تا جدول طراحي مي كنم و مي خواهم از اين به بعد هم از همين روش استفاده كنم و شايد تعداد جداول هم بيشتر بشه.
حالا در تكميل سوالات بالا:
آيا فيلدهايي كه در نظر گرفتم كافي هستند يا بايد اطلاعات ديگري رو هم ذخيره كنم يا اينكه اضافه هستند؟
باتشكر از همكاري شما دوست عزيز

merced
یک شنبه 19 مهر 1388, 15:06 عصر
اينجوري sp رو بنويس


ALTER PROCEDURE [dbo].[sp_Insert]
-- Add the parameters for the stored procedure here
@IDD int ,
@Name nvarchar(50)
AS
BEGIN
BEGIN TRAN T1
INSERT INTO Table2 ([Id] ,[Name_T]) VALUES ( @IDD ,@Name)
SELECT Max(Code) From Table2
COMMIT TRAN T1;
END


و اينجوري فراخواني كن



ADOStoredProc1.Close;
ADOStoredProc1.Parameters[1].Value := 11 ;
ADOStoredProc1.Parameters[2].Value := 'asoduisad' ;
ADOStoredProc1.Open ;
ShowMessage(ADOStoredProc1.Fields[0].AsString);


البته از پارامتر @Return value هم ميشه استفاده كرد كه من چك نكردم

لازم به ذكره كه Code‌ يه فيلد عددي AutoInc‌ هست

merced
یک شنبه 19 مهر 1388, 15:08 عصر
توضيح اينكه وقتي اطلاعات رو درون تراكنش دستكاري يا بازيابي مي كني از لحاظ همزماني خيالت راحته. دو دستور هميشه پشت سز هم اجرا خواهند شد و ...

zman123456
دوشنبه 20 مهر 1388, 08:36 صبح
مرسي از پاسختان
ولي يك سوال اضافه تر
حالا اگه بخواهيم به اين بخش rollback‌اضافه كنيم چكار بايد كرد؟

merced
سه شنبه 21 مهر 1388, 21:38 عصر
ديگه اينو از Help هم مي توني بپرسي :چشمک: حسش نيست برم ببينم :لبخند:

zman123456
پنج شنبه 23 مهر 1388, 09:16 صبح
مرسي از راهنمايي
ولي در مورد فيلدها نظري نداديد كه كمه يا زياد يا مناسب؟
راستي من نيازي به ID‌جدول log ندارم.من مي خوام در جدول log فيلد id‌اون ركوردي كه ثبت شده و مي خواتم لوگشو ثبت كنم رو در جدول log قرار بدم.مشكل من اينه نه به دست آوردن عدد id در جدول log.

merced
پنج شنبه 23 مهر 1388, 16:15 عصر
من هم بر همين اساس نوشتم (استفاده نكردن از Trigger) . يعني شما يه sp براي insert داري كه بعد از insert كردن كد ركورد insert ‌شده به برنامه برمي گردونه حالا اون كد رو با يه دستور ديگه تو جدول Log بذار.
اگه از Trigger استفاده كني بعضي پارامترهايي كه خواسته بودي رو نداري (مثل كد كاربر؛ متن sql و نام فرم ووو. . . )

من بيشتر به اون قسمتي كه گفتي از Select Max‌ نمي خواي استفاده كني توجه كردم و راهي پيشنهاد دادم كه اون دلايلي كه براي استفاده نكردن ازش رو داشتي حذف بشه

Ebrahim Asadi
شنبه 25 مهر 1388, 10:09 صبح
با سلام
من در حال طراحی قابلیت log گیری از عملکرد کاربران در سیستم هستم.
فیلدهایی که در جدول log قرار دادم اینهاست:
usercode-ActionCode-LogDate-RecordID-IP-WindowsUser-QueryText-LogTime
بعضی ها که مشحصه چی هستن.
ActionCode مربوط میشه به هر دکمه در فرم.یک دکمه در کل نرم افزار یک ActionCode به خصوص داره.یعنی unique هست.
recordID فیلد Identity هر جدولی هست که داره در آن اطلاعات درج یا ویرایش یا حذف میشه.
حالا مشکل من در به دست آوردن RecordID در هنگام Insert هست.از گرفتن max(Identity)+1 نمی خواهم استفاده کنم.به دلایل تخصصی که میدونید.
نرم افزار تحت شبکه است.بانک sql 2000.دلفی 7.

سلام
يك سوال و يك جواب دارم:
سوال: ذخيره كردن مقدار Identity جدول ها بدون اين كه نام آن جدول ها را ذخيره كني چه كاربردي دارد؟
و جواب سوال شما:
براي بدست آوردن آخرين Identity جدول، بايد از دستور IDENTITY@@ استفاده كني:


USE Northwind
INSERT INTO Categories (CategoryName) VALUES ('New Category')

DECLARE @LastId INT
SELECT @LastId = @@IDENTITY
PRINT @LastId

zman123456
یک شنبه 26 مهر 1388, 18:13 عصر
سوال: ذخيره كردن مقدار Identity جدول ها بدون اين كه نام آن جدول ها را ذخيره كني چه كاربردي دارد؟

من در كنار اين Identity‌يك فيلد ديگر دارم ثبت مي كنم به نام ActionCode كه اين كد دكمه اي است كه در يك فرم خاص است.كه با اين دكمه دارم روي يك جدول خاص عمل insert انجام ميدم.
از روي نوع Action‌ و كد ActionCode‌مي تونم به جدول هم برسم.اين يكي از پيچيدگيهاي جدول Log منه كه حالا براي روشن شدن مطلب (منو احمق فرض نكنن) نوشتم و هم اينكه شايد به درد دوستان بخوره.

zman123456
پنج شنبه 07 آبان 1388, 10:45 صبح
مرسی از پاسخ های شما.
روشهایی که بیان شد کاملا اصولی و صحیح می باشند ولی یک مشکل دیگری که من دارم اینه که این روش ها به ساختار برنامه نویسی من نخوردند.
یه روش در نظر گرفتم.لطفا نظر بدید.
در هر جدولی که نیاز به log داره فیلد کد کاربری رو اضافه کنم و در هنگامی که می خوام (البته نمی خواستم از این روش استفاده کنم ولی مثل اینکه مجبور شدم) MAX(identity)+1 بگیرم where usercode = x رو به شروط select اضافه کنم.
اینجوری دیگه حتما max همونی هست که می خوام.
البته باید هیچ کاربری از دو سیستم login نکند.

merced
جمعه 08 آبان 1388, 09:06 صبح
اینجوری دیگه حتما max همونی هست که می خوام.
البته باید هیچ کاربری از دو سیستم login نکند.

خوب اين يه ضعف هست. شما دوست داري هنگام گرفتن اطلاعات (موقعInsert ) كليد رو به كاربر نشون بدي.
خوب براي اين كار شما يه جدول در نظر بگير با اين دو فيلذ
نام جدول --- شماره بعدي

وقتي كه خواستي ركورد جديدي ثبت كني مقدار اون فيلد رو از اين جدول بگير و يكي بهش اضافه كن. اگه طرف انصراف رو زد شما چيزي از دست نمي دي فقط شماره ها بينشون هرز ميره. مثلاً مي شه 1-2-3-5-6-9

روش دوم اينه كه با همون Select Max شماره مورد نظر رو به كاربر نشون بدي منتها موقع ذخيره كردن يه بار ديگه اين دستور رو اجرا مي كني و اگه كس ديگه اي اطلاعاتي وارد كرده بود (عددي كه بهش نشون دادي رو گرفته بود) به كاربر اطلاع ميدي كه شماره مورد نظر به فلان شماره تغيير يافت.

zman123456
شنبه 09 آبان 1388, 10:17 صبح
خوب اين يه ضعف هست. شما دوست داري هنگام گرفتن اطلاعات (موقعInsert ) كليد رو به كاربر نشون بدي.
خوب براي اين كار شما يه جدول در نظر بگير با اين دو فيلذ
نام جدول --- شماره بعدي

وقتي كه خواستي ركورد جديدي ثبت كني مقدار اون فيلد رو از اين جدول بگير و يكي بهش اضافه كن. اگه طرف انصراف رو زد شما چيزي از دست نمي دي فقط شماره ها بينشون هرز ميره. مثلاً مي شه 1-2-3-5-6-9

روش دوم اينه كه با همون Select Max شماره مورد نظر رو به كاربر نشون بدي منتها موقع ذخيره كردن يه بار ديگه اين دستور رو اجرا مي كني و اگه كس ديگه اي اطلاعاتي وارد كرده بود (عددي كه بهش نشون دادي رو گرفته بود) به كاربر اطلاع ميدي كه شماره مورد نظر به فلان شماره تغيير يافت.
مرسی از پاسخ.
ولی روش یک رو یه جورایی درک نکردم.یعنی مکانیزم رو نتونستم تو ذهنم بسازم.
نه نیازی به نمایش کلید به کاربر ندارم.
با این توضیح روش دوم هم با همون یک select MAX حل میشه.نه؟
ولی با ترکیب identity و usercode دیگه فکر نکنم مشکلی باشه.ولی این روش من مثل کلک مرغابی میمونه و من اصلا دوست ندارم این جوری کد بنویسم.البته درسته که بعضی اوقات آدم مجبور میشه.
ولی دنبال یک روش خوب می گردم.

merced
شنبه 09 آبان 1388, 14:35 عصر
اصلاً‌ هيج پرنده اي (از جمله مرغابي) در كار نيست.
به نظر من هر جوري كه جواب بده درسته (البته اگه راه ديگه اي به ذهن آدم نرسه)

اگه شما نيازي به نمايش كليد قبل از Insert كردن نداري همون Identity درسته و نياز به چيز ديگه اي نيست. DBMS خودش نميذاره خطايي ايجاد بشه و مواظب Concurrency هست