PDA

View Full Version : ReArrange کردن ستونی خاص با در نظر گرفتن اطلاعات ستونی دیگر با تریگر



HamedFathi
شنبه 24 اردیبهشت 1390, 12:15 عصر
با سلام
متاسفانه من در برنامه نویسی TSQL ضعیف هستم اما موردی پیش آمده که ممنون میشم اساتید گرامی کمک کنند.

من جدولی به نام Group دارم با ستون های
UserName
GroupId
GroupName
که البته هیچ یک کلید اصلی نیستند و UserName خود کلید خارجی است.

لطفا به تصویر 1 نگاه کنید

من میخواهم با استفاده از تریگر پس از عمل Delete ستون GroupID دوباره شماره گذاری شود
مثلا می خواهم برای UserName = ali با استفاده از تریگر ستون GroupID به 1 2 3 تبدیل شود و نیز برای
UserName = hamed با استفاده از تریگر ستون GroupID به 1 2 3 4 5 تبدیل شود و این رویه برای هر عمل Delete نسبت به هر UserName صورت بگیرد

یعنی در کل GroupId همیشه از 1 شروع شود و تا آخر بدون وقفه در توالی اعداد نسبت به هر UserName انجام پذیرد.

آیا این کار در TSQL ممکن است ؟ (تبدیل به تصویر 2)

لطفا راهنمایی بفرمایید

Reza_Yarahmadi
شنبه 24 اردیبهشت 1390, 20:08 عصر
دستور زیر رو برای آپدیت کردن رکوردها بعد از حذف بکار بگیرید
Select T1.UserName, T1.GroupName, GroupId = COUNT(*)
From TableName T1, TableName T2
Where
T1.UserName= T2.UserName
AND
T1.GroupId >= T2.GroupId
Group By
T1.UserName, T1.GroupId, T1.GroupName

محمد سلیم آبادی
شنبه 24 اردیبهشت 1390, 20:19 عصر
اگه نسخه ی 2005 به بالا دارین:

CREATE TRIGGER ReArrangement
ON TableName
AFTER DELETE AS
WITH C AS
(SELECT *, ROW_NUMBER() OVER(PARTITION BY UserName ORDER BY GroupID ASC) AS Rnk
FROM TableName)
UPDATE C
SET GroupId = Rnk
FROM C
WHERE GroupId <> Rnk;

محمد سلیم آبادی
شنبه 24 اردیبهشت 1390, 20:29 عصر
FROM C در عبارت Update غیر ضروری است میتونید ازش صرف نظر کنید.
همچنین چرا جدولتون هیچ کلید اصلی ندارد؟

HamedFathi
شنبه 24 اردیبهشت 1390, 21:51 عصر
FROM C در عبارت Update غیر ضروری است میتونید ازش صرف نظر کنید.
همچنین چرا جدولتون هیچ کلید اصلی ندارد؟

ممنونم msalim عزیز اتفاقا خیلی دوست دارم دیاگرام کامل دیتابیس رو با یک شرح مختصر قرار بدم تا عیوب طراحی دیتابیسم گرفته بشه، در هر حال این فقط یکی از 5 جدول موجود هستش حقیقتا UserName در جدول دیگری (Account) کلید اصلی است و اینجا کلید خارجی چون هر UserName میتونه چند گروه داشته باشه و این گروه ها با ایندکس TreeView برنامه ی سی شارپم مرتبط هستش به این شکل در نظر گرفتم (البته مطمئن نیستم که بهتر از این نمیشد !)
در کل من در طراحی دیتابیس خیلی ضعیفم و الانم در گیر پروژه دانشگاهم که به مشکلاتی برخوردم در هر حال از راهنمایی شما ممنونم

یا حق

محمد سلیم آبادی
شنبه 24 اردیبهشت 1390, 23:07 عصر
حقیقتا UserName در جدول دیگری (Account) کلید اصلی استاگه نام کاربری مثل این سایت توسط خود کاربر مشخص بشه، پیشنهاد میکنم این ستون رو یونیک در نظر بگیرید و یک ستون دیگه به نام user_nbr از نوع Integer ایجاد کنید و به عنوان کلید اصلی در نظر بگیرید.
در جدول Group هم بنظر میرسه ترکیب دو ستون UserName و GroupID منحصر بفرد هست. پس می تونید ترکیب این دو رو کلید اصلی در نظر بگیرید.

دلیل اینکهباید این مقادیر (groupid) دقیقا پشت سر هم باشن و هیچ گپی بینشون نباشه رو نمیدونم. ولی اینو میدونم این عبارت update که تو تریگیر اجرا میشه هزینه بالایی رو به سیستم به ازای هر حذفی تحمیل میکنه.

HamedFathi
یک شنبه 25 اردیبهشت 1390, 00:05 صبح
ممنونم msalim عزیز حالا که لطف کردی و توضیح دادی بد ندیدم دیاگرام رو کامل قرار بدم و اگر ممکن باشه از راهنمایی های شما بهره ببرم

متاسفانه من در حال حاضر در طراحی و کد نویسی دیتابیس ضعیف هستم :ناراحت:

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

1. بله UserName توسط کاربر منظور میشه اصلا جدول Account اطلاعات ثبت نامی را ذخیره میکند. (کاربر خودش ثبت نام میکند)

2. جدول Security سوالات امنیتی رو ذخیره میکند و SecurityId مطابق با ایندکس ComboBox برنامه ی Winform است. یا بهتر بگم پس از لود جدول این ComboBox است که مطابق جدول Security پر میشود
* در کل کاربر امکان بازیابی پسورد را با توجه به سوال امنیتی هنگام ثبت نام را داراست.

3.پرسیدید که چرا نباید گپی در GroupId باشد چون این اعداد مطابق Node های TreeView در برنامه ی من هستند و وجود گپ در Update , Delete و Insert گروه ها مشکل ایجاد میکند Node شماره یک دقیقا به GroupId اولی اشاره میکند و این همین طور ادامه میابد حالا اگر یکی از Node ها از Treeview حذف شود مثلا گره 3 (از 7 گره موجود) Treeview ترتیب Node ها را از 1 تا 6 بدون هیچ گپی بازسازی میکند من برای از بین بردن این عدم تطابق مجبور به این کار شدم
اما گفته ی شما 100 درصد صحیح می باشد

* البته میشد از ساختمان داده خاصی استفاده کنم و تو لایه ی برنامه هوشمندانه این تغییرات رو کنترل کنم !!!
در عین حال هر کاربر می تواند چند گروه داشته باشد،
GroupId کلید اصلی نیست چون یکتایی وجود ندارد (اما موردی که شما فرمودید را حتما مد نظر قرار میدهم ممنونم)
مثلا Ali گروه 1 تا 4 دارد با نام های ... و
Reza گروه 1 تا 7 دارد با نام های ...

در هر حال از شما متشکرم