PDA

View Full Version : سوال: RollBack و مشکل در ستون Identity



razavi_university
دوشنبه 06 خرداد 1387, 09:25 صبح
با سلام خدمت دوستان
من براي چک کردن تکراري بودن مقادير ورودي به جدول يک Trigger روي جدول مورد نظر گذاشتم و به خوبي هم کار مي کنه و در صورتي که مقادیر وارد شده تکراري باشه RollBack انجام ميده
ولي چون ستون Primary اين جدول Identity شده هر بار که مقادير تکراري باشند و RollBack انجام شود به Identity يک واحد افزوده مي شود در صورتي که هيچ مقداري درون جدول وارد نشده.
چطور ميشه اين Identity اضافي رو خنثي کرد؟

کدTrigger:


ALTER TRIGGER [dbo].[CheckDuplicate]
ON [dbo].[Batch]
AFTER INSERT,UPDATE
AS
IF ( SELECT COUNT(*) btname FROM Batch,inserted WHERE Batch.btname=inserted.btname ) > 1
BEGIN
PRINT N'مقدار تکراری است';
ROLLBACK TRANSACTION
END


خواستم با Reseed درستش کنم نشد


use depot
DBCC CHECKIDENT ( 'Batch', RESEED )

razavi_university
سه شنبه 07 خرداد 1387, 09:53 صبح
آیا میشه کاری کرد که وقتی RollBack میشه Identity هم اضافه نشه و مقدار قبلیش باقی بمونه؟

Behrouz_Rad
سه شنبه 07 خرداد 1387, 12:02 عصر
چرا از Trigger استفاده می کنی؟ از یک شرط IF ساده استفاده کن!

SabaSabouhi
سه شنبه 07 خرداد 1387, 14:27 عصر
آیا میشه کاری کرد که وقتی RollBack میشه Identity هم اضافه نشه و مقدار قبلیش باقی بمونه؟

با سلام
نه نمى‌شه.
مگه اين كه بجاى Identity يك ستون از جنس Interger داشته باشى و Identity رو خودت شبيه‌سازى كنى.

حالا اين رو براى چى مى‌خواى؟
اگه منظورت يه چيزى تو مايه‌هاى شماره فاكتور يا شماره سند در سيستم‌هاى فروش و مالى هست حتماً خودت اون ها رو از طريق يك Trigger يا StoredProcedure ( بسته به اين كه با كدوم راحت‌تر هستى ) كنترل كن، Identity اصلاً به درد اين كار نمى‌خوره.

صبا صبوحى

razavi_university
سه شنبه 07 خرداد 1387, 15:30 عصر
چرا از Trigger استفاده می کنی؟ از یک شرط IF ساده استفاده کن!

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


با سلام
نه نمى‌شه.
مگه اين كه بجاى Identity يك ستون از جنس Interger داشته باشى و Identity رو خودت شبيه‌سازى كنى.

حالا اين رو براى چى مى‌خواى؟
اگه منظورت يه چيزى تو مايه‌هاى شماره فاكتور يا شماره سند در سيستم‌هاى فروش و مالى هست حتماً خودت اون ها رو از طريق يك Trigger يا StoredProcedure ( بسته به اين كه با كدوم راحت‌تر هستى ) كنترل كن، Identity اصلاً به درد اين كار نمى‌خوره.

من می خوام شماره عضویت رو در این فیلد نگه داری کنم و Seed اون سال ورود باشه که در ابتدای هر سال توسط برنامه اضافه می شه

البته کار نشد نداره:چشمک:
میشه در هنگام Select در Triggerمقدار Max ستونIdentity رو در بدست اورد و با با همین Max ستون رو reseed کرد
ولی می خوام بدونم کسی نطر دیگه ای نداره یا روشی دیگه واسه اینکار؟ ؟ ؟
ممنون میشم اگر دوستان نظرشون رو بگن

Behrouz_Rad
سه شنبه 07 خرداد 1387, 15:49 عصر
منظورتون اینه که که چک تکراری بودن رو در برنامه انجام بدم.

خیر. با IF NOT EXISTS از طریق T-SQL در SP

razavi_university
چهارشنبه 08 خرداد 1387, 16:12 عصر
خیر. با IF NOT EXISTS از طریق T-SQL در SP

منظورتون اینه که یه SP بنویسم و در اون تکراری بودن رو چک کنم و قبل از هر Insert اون SP رو اجرا کنم و بر اساس چواب اون SP برای insert تصمیم بگیرم؟

اگر منظورتون رو درست نگرفتم بفرمایید؛ مشکل من در جستجوی مقدار تکراری نبود بلکه با Identity های اضافه شده مشکل داشتم.

SabaSabouhi
چهارشنبه 08 خرداد 1387, 16:42 عصر
من می خوام شماره عضویت رو در این فیلد نگه داری کنم و Seed اون سال ورود باشه که در ابتدای هر سال توسط برنامه اضافه می شه

البته کار نشد نداره:چشمک:


با سلام
كاملاً حق با شماست، كار نشد نداره.
اما به‌تره از هر چيزى جاى خودش استفاده بشه. به نظر من Identity براى اين كار ساخته نشده و ممكنه براتون مشكل ايجاد كنه.

صبا صبوحى

razavi_university
چهارشنبه 08 خرداد 1387, 19:09 عصر
با سلام
كاملاً حق با شماست، كار نشد نداره.
اما به‌تره از هر چيزى جاى خودش استفاده بشه. به نظر من Identity براى اين كار ساخته نشده و ممكنه براتون مشكل ايجاد كنه.

سلام
کم کم خودم هم دارم به همین نتیجه می رسم که از Identity استفاده نکنم، توصیه یکی از دوستانم هم همین بود که در سیستم تجاری که قراره چندین سال کار کنه از Identity استفاده نکنم (ولی دلیل خاصی رو نگفت)
لطف کنین اگه دلیل مستند و خاصی رو برای کنار گذاشتن Identity مد نظر نظر دارین بگیید و اینکه چه راهی رو به جای Identity پیشنهاد می کنید؟
ممنون

SabaSabouhi
شنبه 11 خرداد 1387, 10:46 صبح
سلام
کم کم خودم هم دارم به همین نتیجه می رسم که از Identity استفاده نکنم، توصیه یکی از دوستانم هم همین بود که در سیستم تجاری که قراره چندین سال کار کنه از Identity استفاده نکنم (ولی دلیل خاصی رو نگفت)
لطف کنین اگه دلیل مستند و خاصی رو برای کنار گذاشتن Identity مد نظر نظر دارین بگیید و اینکه چه راهی رو به جای Identity پیشنهاد می کنید؟
ممنون

سلام
دوست عزيز، شايد من بد گفته باشم.
من نگفتم كه از Identity استفاده نكنيد. گفتم كه به‌جاى يك فيلد معنى دار استفاده نكنيد.
مثلاً در سيستم فروش، من يك InvoiceID دارم كه Identity و PrimaryKey هست و در ارتباط بين جدول‌ها ازش استفاده مى‌كنم و يك InvoiceNumber دارم كه شماره فاكتور هست و كاربر اون رو مى‌بينه. چون شماره فاكتور در هر سال بايد يكتا باشه يك انديس يكتا ( ‌Unique Index ) ايجاد مى‌كنم براى سال صدور فاكتور و شماره فاكتور.
حالا اگه لازم بود به هر دليل ( قانونى يا غير قانونى :لبخندساده: ) شماره فاكتورى اصلاح بشه هيچ مشكلى تو ارتباط جدول‌ها پيش نخواهد اومد.
در واقع به بيان ديگه InvoiceID مال منه! و InvoiceNumber مال كاربر. دعوامون هم نمى‌شه ديگه.

صبا صبوحى

Arghavan_Reza
شنبه 11 خرداد 1387, 15:37 عصر
دوستان با سلام،
بهتره برای هر جدول یک فیلد ID بعنوان PrimaryKey در نظر بگیرید. و بهتره که IDENTITY نباشد، همان معضل RollBack را دارد و جای خالی آن هم پر نمیشه، و نمیشه فهمید واقعا چه رکوردهایی اضافه و سپس حذف شده اند. برای فیلدهای شماره سند و فاکتور و ... از فیلد دیگری استفاده نمایید و جهت تکراری نبودن آن از UNIQUE INDEX استفاده نمایید و خطای SQL را در برنامه Handle نمایید. جهت شماره گذاری ID و شماره سند و ... می توانید تریگر INSTEAD OF INSERT استفاده نمایید و در آن از تابع MAX استفاده نمایید.
البته راه دیگری هم وجود دارد سریعتر است ولی 100% تایید نمی شود مگر در مواردی که مطمئن باشید فرد خارجی به DB دسترسی ندارد. یک جدول ایجاد نمایید که حاوی بیشترین مقدار ID جداول باشد (یا شماره سند و شماره فاکتور ) و با اضافه شده قطعی هر رکورد مقدار ID یکی اضافه شود و این مقدار حداکثر توسط Query یا SP خوانده و Update شود. البته ممکن است راه های بهتری هم وجود داشته باشد.