# پایگاه‌های داده > SQL Server > T-SQL >  نحوه تشحیص خروج نامتعارف کاربر از برنامه تحت شبکه

## Sal_64

سلام. بانک من روی شبکه ست و کاربرها با وارد کردن نام کاربری و پسورد (از طریق برنامه تحت ویندوز) بهش متصل میشن . و اطلاعات کاربر لاگین شده (به اضافه اطلاعات سیستم لاگین کننده) در تیبل A ثبت می شود تا از ورود مجدد آن کاربر از سیتمی دیگر جلوگیری بشه و در زمان خروج از برنامه اطلاعات کاربر از تیبل A حذف می شود. سوالم اینه اگه سیستم کاربر به هر دلیلی دچار مشکل بشه و دستور حذف رکورد از تیبل  A به بانک ارسال نشه ، در زمان لاگین مجدد از سیتمی دیگر چه شکلی بانک از این موضوع با خبر بشه و رکورد مزاحم حذف بشه؟؟  تشکر

----------


## hamid-nic

سلام
این روش جالبی نیست چون اگر به هر دلیلی مثلا رفتن برق سیستم شخص نتونه عملیات خروج را انجام بده با این مشکل روبرو می شوید اما در این مورد می توانید بصورت دوره ای مثلا هر نیم ساعت یا یک ساعت یک بار اون جدول را توسط برنامه ای یا تریگری چک کنید اگر چنین موردی بود حذف بشه . منظور اینکه مثلاً دوره ای اطلاعات اون جدول بروز و در صورت امکان اطلاعات غیر ضروری یا با مقدار ساعت ثبت شده بیش از حد حذف بشه . البته می توانید خیلی بهتر این پروسه را پیاده کنید که با این مشکلات روبرو نشوید.

----------


## Sal_64

> سلام
> این روش جالبی نیست چون اگر به هر دلیلی مثلا رفتن برق سیستم شخص نتونه عملیات خروج را انجام بده با این مشکل روبرو می شوید اما در این مورد می توانید بصورت دوره ای مثلا هر نیم ساعت یا یک ساعت یک بار اون جدول را توسط برنامه ای یا تریگری چک کنید اگر چنین موردی بود حذف بشه . منظور اینکه مثلاً دوره ای اطلاعات اون جدول بروز و در صورت امکان اطلاعات غیر ضروری یا با مقدار ساعت ثبت شده بیش از حد حذف بشه . البته می توانید خیلی بهتر این پروسه را پیاده کنید که با این مشکلات روبرو نشوید.


تشکر از پاسختون . بله دقیقا اگر به هر دلیلی کاربر بدون شیوه مرسوم خارج بشه آن رکورد در تیبل A باقی خواهد موند . از اونجایی که در هر سستم تنها یک نسخه از برنامه اجرا خواهد شد . اگر همان کاربر صاحب سیستم 001  پس از خروج نامتعارف دوباره بخواد از سیستم 001 لاگین کنه مشکلی نیست اما اگه از سیستم 002 لاگین کنه ، نمیشه تشخیص داد که آیا بصورت همزمان قصد داره از دو تا سیستم لاگین کنه و یا اینکه سیستم خودش دچار مشکل شده . استفاده از تریگر که هر نیم ساعت برنامه بررسی کنه اولا اینکه شیوه فنی پیاده کردنش نمی دونم و مورد بعد اینکه کاربرها خیلی با هم جیجی باجی هستن  و فاصله بین سیستم هاشون به یک متر هم نمی رسه پس در صورت بروز هر مشکلی سریع از سیتم همدیگه لاگین میکنن و زمان نیم ساعت زمان بسیار زیادیه برا چک کردن !!     شما چه راه حلی رو پیشنهاد میکنید؟؟  تشکر

----------


## ASKaffash

سلام
روشهائی که می خواهند حضور یا عدم حضور واقعی یک کاربر را دریک برنامه تحت شبکه تشخیص دهند اینطوری نیست که یک Flag در بانک مدیریت شود چون خودتان اشکالات اصلی را ذکر کردید فنی ترین روش این است که شما در جدول کاربران خود پس از ورود هر کاربر به برنامه رکورد آن کاربر را Lock نگه دارید اینطوری حتی با یک User از دو Station نمی توان Login کرد و با یک Query ساده و مدیریت خطا می توانید فهرست کاربران متصل واقعی را تشخیص دهید کاربری که بصورت غیرنرمال خارج شود توسط بانک اطلاعاتی چون Connection را از دست میدهد بنابراین Lock آن اتوماتیک آزاد میگردد و فیلدهای مورد نظر شما مثل تاریخ و ساعت خروج آن پر نشده هستند دستور Lock کردن در SQLServer مثلا شبیه این کد است :

Set Tran Isolation Level Serializable
Begin Tran
Select * From Users With (RowLock) Where UserID=5

----------


## Sal_64

سلام . تشکر. اگه درست متوجه شده باشم . تنها باید پس از هر لاگین آن رکورد کاربر در تیبل user لاک کنم . با همین دستوری که گفته شده ؟ درسته ؟ و در صورت خروج نامتعارف باقی کارها  sql انجام میده سریعا (در مدت چند ثانیه پس از خروج نامتعارف)  ؟ درسته ؟

----------


## ASKaffash

سلام
بله تست کنید متوجه خواهید شد

----------


## hamid-nic

اصولاً برنامه هایی که مستقیماً به بانک اطلاعاتی متصل می شوند این مشکل را دارند بهتر است که برنامه بصورت کلاینت سرور همراه با سرور اپلیکیشن برای کنترل بیشتر و بهتر  باشه یا  اگر از دلفی برای نوشتن استفاده می کنید از تکنولوژی جدید DataSnap استفاده کنید که با چنین مشکلاتی روبرو نشوید .

آقای کفاش عزیز در مورد کدتون :
 طریقه ی update یا insert در این حالت که فرقی با حالت عادی نداره ؟



> فیلدهای مورد نظر شما مثل تاریخ و ساعت خروج آن پر نشده هستند


  و اینکه اطلاعات اون جدول باید مثلاً فیلدهای تاریخ و ساعت ورود و خروج update بشه یا کلا هر بار از نو اطلاعات وارد بشه ؟

----------


## ASKaffash

سلام
قطعا این روش باید اندکی تغییر کند هنگام ورود زمان در یک فیلد ثبت میگردد و فیلد زمان خروج خالی می شود حال برنامه هنگام خروج فیلد را پر می کند سه حالت اتفاق می افتد :
- اگر رکورد لاک باشد و فیلد خروج خالی باشد یعنی کاربر فعال است
- اگر رکورد لاک نباشد و فیلد خالی باشد یعنی کاربر خروج نامتعارف داشته است
- اگر رکورد لاک نباشد و فیلد پر باشد خروج نرمال بوده است
در ضمن برای نگه داشتن ورودها و خروجهای کاربر حتما یک جدول Master/Detail ایجاد گردد و آخرین تاریخ ورود یعنی آخرین فعالیت کاربر است

----------


## Sal_64

سلام. سعی کردم این دستور داخل sp پیاده کنم . اما پس از اجرای اون جوابی نگرفتم. احتمالا دقیق متوجه منظور شما نشدم . میشه بیشتر راهنمایی کنید. تشکر     ALTER PROCEDURE [dbo].[check_pass]          (     @user_name Nvarchar(50),     @password Nvarchar(50)      )      AS     /* SET NOCOUNT ON */      select count(*) from user_define where (user_name=@user_name and password=@password)  Set Tran Isolation Level Serializable Begin Tran Select * From user_define With (RowLock) Where user_name=@user_name      RETURN

----------


## ASKaffash

سلام
اگر Connection بسته شود حتما Lock ها آزاد می شوند دقت کنید که این Connection باید باز بماند شما در زبان برنامه نویسی چگونه از RowLock استفاده میکنید ؟

----------


## Sal_64

سلام. ببینید همه ارتباط من از برنامم (تحت ویندوز) با بانک داده برای ورود کاربر ، فقط و فقط همین sp و داخل خود برنامه چیزی ندارم . اگه جایی نیاز به توضیح بیشتر بود حتما بگید.تشکر

----------


## ASKaffash

سلام
با چه زبان برنامه نویسی کد نوشته اید یا اینکه بخش برنامه ای که این SP را صدا میزند را قرار دهید

----------


## Sal_64

سلام. همونطور که گفتم برنامه تحت ویندوز و به زبان سی شارپ و این sp در زمان لاگین کاربر اجرا میشود. اگه نیاز به توضیحات بیشتر هست حتما بگید . تشکر

----------


## ASKaffash

سلام
کد را قرار دهید تا برایتان اصلاح کنم

----------


## Sal_64

> سلام
> کد را قرار دهید تا برایتان اصلاح کنم


سلام . تشکر . ببینید کد من چیز خاصی نیست فقط یوزر و پسورد تایپ شده توسط کاربر گرفته و به اون sp که در چند پست قبل کدش گذاشتم میفرسته ، همین کد خاصی نیست. اگه باز نیاز به توضیح بیشتر هست حتما بگید . تشکر

----------


## Sal_64

سلام- همچنان منتظر راهنمایی های بی دریغ دوستان هستم- تشکر

----------


## ASKaffash

سلام
با اجازه آقای صادقیان مجبورم در تالار SQLServer به زبان #C بنویسم:
در کد ذیل تا زمانیکه 5 دقیقه Sleep تمام نشده باشد Session باز است و رکورد قفل می ماند از جائی دیگر (برنامه ای دیگر / کام÷یوتر دیگر / ... ) سعی کنید روی رکورد مورد نظر دستور Update صادر کنید می بینید که نمی شود

int Min = 5;
SqlConnection C = new SqlConnection(".......");
C.Open();
DataTable DT = new DataTable();
new SqlDataAdapter("Set Tran Isolation Level Serializable Begin Tran Select * From Users With (RowLock) Where UserID=1", C).Fill(DT);
System.Threading.Thread.Sleep(Min * 60000);
C.Close();

----------


## Sal_64

سلام - تشکر- ببینید من فقط یکبار اونم در لحظه  ورود کاربر این قضیه چک میکنم - اگه درست متوجه شده باشم راهکار شما در هر بار ارتباط با بانک باید این روال در پیش بگیره؟ درسته؟

----------


## ASKaffash

سلام
نه باید همیشه در طول برنامه این Connection را حفظ کنید در غیر اینصورت وجود کاربر را تشخیص نخواهید داد (شی C خیلی مهم است)

----------


## Sal_64

> سلام
> نه باید همیشه در طول برنامه این Connection را حفظ کنید در غیر اینصورت وجود کاربر را تشخیص نخواهید داد (شی C خیلی مهم است)


سلام - به چه طریق باید حفظ شه؟- با تایمر؟ تشکر

----------


## ASKaffash

سلام
می تونه یک شی Static باشد که در ابتدی برنامه استفاده شود و در زمان خروج Dispose گردد

----------


## Sal_64

> سلام
> می تونه یک شی Static باشد که در ابتدی برنامه استفاده شود و در زمان خروج Dispose گردد


سلام- بازم تشکر- من از طریق دیگه ای عمل کردم و روی کاغذ جواب گرفتم - فقط یه سوال آیا می توان با استفاده از دستوران sql ، آی پی سیستمی در شبکه ping کرد و نتیجه دید؟ تشکر

----------


## oliya24

میشه خواهش کنم نتالیج کارهاتون رو برای من و دیگران هم بگذارید ممنون میشم

----------


## ASKaffash

سلام
بله اگر نسخه بالای 2005 داشته باشید و دات نت کار هم باشید می توانید با طراحی یک Assembly با دات نت در SQL استفاده کنید در دات نت Ping با استفاده از کلاس new System.Net.NetworkInformation.Ping() است

----------


## Sal_64

> سلام
> بله اگر نسخه بالای 2005 داشته باشید و دات نت کار هم باشید می توانید با طراحی یک Assembly با دات نت در SQL استفاده کنید در دات نت Ping با استفاده از کلاس new System.Net.NetworkInformation.Ping() است


سلام - تشکر- پاسخ شما چندین مرتبه خوندم - اما ... -ظاهرا توضیحات من کافی نبوده  ببینید sql2005 و من میخوام sp طراحی کنم که به وسیله اون sql نصب شده روی سرور بتونه کلاینت ها ping کنه و از نتیجه اون در برنامم(#C) استفاده کنم .

----------


## ASKaffash

سلام
متوجه توضیح شما شدم : شما میخواهید با استفاده از T-SQL تعدادی Client را Ping کنید و با دستور Select استخراج ودر زبان برنامه نویسی استفاده کنید درست است ؟
بنابراین جواب همان Assembly است حتی دربرنامه های Web Base و غیر دات نتی هم این روش قابل استفاده است

----------


## Sal_64

> سلام
> متوجه توضیح شما شدم : شما میخواهید با استفاده از T-SQL تعدادی Client را Ping کنید و با دستور Select استخراج ودر زبان برنامه نویسی استفاده کنید درست است ؟
> بنابراین جواب همان Assembly است حتی دربرنامه های Web Base و غیر دات نتی هم این روش قابل استفاده است


سلام - یه دنیا تشکر- میشه درباره اسمبلی اینکه چی هست و چجوری باید ازش استفاده کرد هم توضیح کوتاهی بدین- تشکر

----------


## ASKaffash

سلام
یک DLL با یکی از زبانهای دات نت بنویسید و توابع مورد نظر خود را پیاده سازی کنید (در مثال شما متدی برای Ping یک IP) و در SQLServer توابع این DLL را بااستفاده از Create Assembly معرفی کنید و مثل توابع UDF طراحی شده درون SQLServer درون دستورات T-SQL آنها را بکار ببرید درون Help خود SQLServer نمونه وجود دارد (در واقع شما دات نت را در خدمت SQLServer در می آورید)

----------


## Sal_64

> سلام
> یک DLL با یکی از زبانهای دات نت بنویسید و توابع مورد نظر خود را پیاده سازی کنید (در مثال شما متدی برای Ping یک IP) و در SQLServer توابع این DLL را بااستفاده از Create Assembly معرفی کنید و مثل توابع UDF طراحی شده درون SQLServer درون دستورات T-SQL آنها را بکار ببرید درون Help خود SQLServer نمونه وجود دارد (در واقع شما دات نت را در خدمت SQLServer در می آورید)


سلام- تشکر- خیلی دوس داشتم اینکار به تنهایی انجام بدم و دوباره شما تو زحمت نندازم- راهی که رفتم این بود با سی شارپ dll آزمایشی ایجاد کردم و بعد از داخل management studio و با انتخاب بانک مورد نظر و سپس Assemblies گزینه new و سپس آدرس dll بهش دادم و owner هم dbo انتخاب کردم - اما نه با دستور select و نه exec نتونستم اجراش کنم- میشه بیشتر راهنمایی کنید - تشکر

----------


## ASKaffash

سلام
بنظرم عنوان تاپیک از مسیر اصلی منحرف شده موضوع ایجاد Assembly با #C کمی پیچیده است اگر تمایل داشته باشید یک تاپیک مناسب بنام ایجاد Ping با استفاده از Assembly دات نت با #C ایجاد کنید و من صفر تا 100 را با سورس Ping ارائه دهم تا برای دیگران نیز مفید واقع گردد

----------


## Sal_64

> سلام
> بنظرم عنوان تاپیک از مسیر اصلی منحرف شده موضوع ایجاد Assembly با #C کمی پیچیده است اگر تمایل داشته باشید یک تاپیک مناسب بنام ایجاد Ping با استفاده از Assembly دات نت با #C ایجاد کنید و من صفر تا 100 را با سورس Ping ارائه دهم تا برای دیگران نیز مفید واقع گردد


https://barnamenevis.org/showthread.p...46#post1594946

----------

