PDA

View Full Version : ساخت فرمول برای کلید اصلی در شبکه



Developer Programmer
دوشنبه 14 اردیبهشت 1388, 22:42 عصر
یه برنامه تحت شبکه ثبت نام دانشجویی رو در نظر بگیرین.
وقتی یک دانشجو برای اولین بار ثبت نام میکنه، واسش یه کد میدن.
کد میتونه به این شکل باشه 81666764 که دو رقم اول مربوط به سال تحصیلی باشه، دو رقم بعد مربوط به کد گروه و بیقه رقم ها مربوط به خود دانشجو باشه

میخوام بدونم، در یک برنامه تحت شبکه، چطور میتونن واسه کلید اصلی فرمول بسازن و Insert کنن که مشکل همزمانی و قفل پیش نمیاد؟

آخرین رکورد رو میخونه Lock میکنه و بعد از Insert اونرو unlock میکنه؟ اینطوری کارائی پایین نمیاد؟

meysam_pro
سه شنبه 15 اردیبهشت 1388, 09:06 صبح
درخواستها در SQL در یک صف قرار میگیرین در نتیجه این مشکل پیش نمیاد ، اما در MySql خودتون باید کنترل بکنین.

Developer Programmer
سه شنبه 15 اردیبهشت 1388, 15:14 عصر
درخواستها در SQL در یک صف قرار میگیرین در نتیجه این مشکل پیش نمیاد


در یک برنامه تحت شبکه، چطور میتونن واسه کلید اصلی فرمول بسازن
مطمئنی مشکلی پیش نمیاد؟ وقتی هر کس از یک کامپیوتر داره ثبت نام میکنه، تقاضاها در یک صف قرار میگیرن؟

Microsoft.net
چهارشنبه 16 اردیبهشت 1388, 10:53 صبح
درخواستها در SQL در یک صف قرار میگیرین در نتیجه این مشکل پیش نمیاد ، اما در MySql خودتون باید کنترل بکنین.

کی همچین حرفی زده ؟ منبع ؟!!! صف یعنی اجرای سری دستورات !!! یعنی 4 تا یوزر request میفرستن اول شماره 1 اجرا میشه بعد شماره 2 بعد ... ! مسخره است...

Developer Programmer
چهارشنبه 16 اردیبهشت 1388, 13:47 عصر
یافتم!

راه حل رو میذارم شاید به درد کسی خورد.

با تشکر از علی کشاورز که من رو به راه حل نزدیک کرد


...راه دیگه میتونه در سیستم های Client\Server این باشه که کد با استفاده از Trigger بطور خودکار توسط بانک اطلاعاتی تولید بشه.
راه دیگه هم میتونه این باشه که یک شماره ID منحصر به فرد برای هر دانشجو ایجاد بشه، و برای نمایش آن به کاربر، یک فیلد محاسباتی ایجاد بشه که مقدار این ID را با مقادیر فیلدهای سال ورود و گروه آموزشی ترکیب میکنه، و به کاربر ارائه میکنه. یا Primary Key از ترکیب چند فیلد ساخته شده باشه، مثلا از ترکیب فیلدهای سال ورود، گروه آموزشی، و ID فرد که بطور خودکار توسط بانک تولید شده.
و این تقریبا همان چیزی بود که من همیشه بهش فکر میکردم اما هم پیاده سازیش رو بلد نبودم و هم از صحت عملکردش مطمئن نبودم.

طبق مطلب علی کشاورز و مقاله Custom Auto-Generated Sequences with SQL Server ، اصول کار اینطوره که میان یه Primary Key از نوع AutoNumber میگیرن و اجازه میدن که به ازای هر رکورد اتوماتیک زیاد بشه.
بعد یه فیلد مجزا تعریف میکنن و به ازای هر رکورد اونرو طوری مقدار دهی میکنن که با فرمول مورد نظر مطابقت کنه.
مثلا :
فرض کنین که یه همچین جدولی دارین:


create table Customers
(
dbID int identity not null primary key,
CustomerName varchar(100)
)
و میخوایم فرمول کد پرسنلی اینطور باشه


C0001
C0002
...
C9998
C9999
واسه همین ، میایم و یه فیلد جدید تعریف میکنیم:


alter table Customers add CustomerNumber as dbo.CustomerNumber(dbID)
اما dbo.CustomerNumber چیه ؟! در حقیقت ، یه Function که فرمول رو تولید و نتیجه رو به فیلد CustomerNumner پاس میده


create function CustomerNumber (@id int)
returns char(5)
as
begin
return 'C' + right('0000' + convert(varchar(10), @id), 4)
end
به همین راحتی !

ضمن اینکه اینطور هم میتونین عمل کنین:


alter Customers add CustomerNumber varchar(10)
یعنی فیلدی تعریف کردیم اما مقدارش رو از داخل Trigger بهش میدیم:


create trigger Customers_insert on Customers
after insert as
update
Customers
set
Customers.customerNumber = dbo.CustomerNumber(Customers.dbID)
from
Customers
inner join
inserted on Customers.dbID= inserted.dbID
بعد از هربار عمل Insert، تریگر فعال میشه و فیلد CustomerNo رو در سطر جدید با مقدار تولید شده از فانکشن، Update میکنه

در صورت استفاده از هر دو راه حل، جواب یکسانه



insert into Customers (CustomerName) values ('jeff')
select * from Customers

returns:

(1 row(s) affected)

dbID CustomerName CustomerNumber
----------- ------------ --------------
1 jeff C0001

(1 row(s) affected)
1) بزرگترین مزیتی که این روش داره اینه که ، همه چیز در Server Side انجام میشه و باعث ترافیک شبکه و رد و بد شدن اطلاعات اضافی نمیشه.
2) در برنامه های تحت شبکه که امکان گم شدن، آخرین کلید درج شده توسط کاربران هست، بهتره از SCOPE_IDENTITY استفاده بشه که توضیحش در MSDN اومده



Returns the last identity value inserted into an identity column in the same scope. A scope is a module: a stored procedure, trigger, function, or batch