ورود

View Full Version : identity کردن یک ستون



jd.mn98
چهارشنبه 16 مرداد 1392, 12:07 عصر
دوستان سلام

من یک ستون از جدولم رو identityش رو فعال کردم که هر چی وارد کنم خودش به طور اتوماتیک شماره بندی کنه . من چند مورد که وارد کردم مثلا 12 تا ، تا 12 شماره گذاری کرد بعدش 2 مورد رو پاک کردم طبیعتا تا ردیف 10 موند.
اما وقتی خواستم تا یک مورد دیگه اضافه کنم از 13 شروع کرد ، من می خواستم از 11 بره ولی از 13 رفت
حالا می خوام بدونم چرا اینطوری شده و راه حلی داره یا نه.

sajadsobh
چهارشنبه 16 مرداد 1392, 15:12 عصر
سلام.
چون مقدار Identity میشه گفت مثل یه شمارنده میمونه که به ترتیب یکی یکی یا هرجور که تعیین بشه اضافه میشه. و چون اینکار خودکار انجام میشه امکان اینکه هر دفعه شما رکوردی رو delete میکنی مقدارش برگرده به حالتی که میخوای رو نداره.
یه راه حل داره که از اونجایی که میخوای seedدهی کنی و اونم اینه که تو قسمت Query Editor این کد رو بنویسی:

DBCC CHECKIDENT('Table_name', RESEED, NewReseedValue)

Table_name که اسم جدول مورد نظره
RESEED یعنی اینکه میخوای مقدار identity رو دوباره مقداردهی کنی
NewReseedValue هم عددی هست که میخوای از اونجا شروع بشه البته باید یه عدد قبلش رو توی کد قرار بدی، مثلاً اگه قرار باشه از 5 شروع بشه دوباره شما باید عدد 4 رو وارد کنید. یه مثال میزنم.

DBCC CHECKIDENT('tbl_Sample', RESEED, 10)

الان من یه جدول دارم به اسم tbl_Sample که میخوام ستون Identity از 11 شروع بشه.

محمد سلیم آبادی
پنج شنبه 17 مرداد 1392, 10:02 صبح
حالت های مختلفی وجود داره که آخرین id جدول با آخرین id تولید شده اختلاف پیدا میکنند و در این بین شکاف بوجود میاد.
شما مورد حذف را مثال زدین و من به چند مورد دیگه اشاره میکنم. فرض کنید یک عبارت Insert می نویسید ولی با شکست مواجه میشه خب در اینجا یک مقدار به identity اضافه میشه. و درج سطر بعدی به این شکاف پی خواهید برد. یک مورد دیگر اینه که شما فرضا 100 رکورد در جدول درج کردین در یک تراکنش حالا این تراکنش rollback میشه. خب مقدار identity صد واحد افزایش پیدا کرده و هیچگاه نیز این مقدار به عقب بر نمیگرده.
آیا شما میخواهید دائما آخرین مقدار identity تولید شده و آخرین id درج شده در جدول را باهم مقایسه کنید و در صورت لزوم آن را توسط reseed به مقدار مورد نظر برگردانید؟!

و سوال بعد حالا چه میشود اگر سطرهای میانی جدول حذف بشن. باز در این حالت شکاف بوجود میاد بین مقادیر identity حالا چه می خواهید بکنید؟ میخواهید تمام دادهای بعد از شکاف را شیف کنید؟! این امکان پذیر نیست به این دلیل که خصیصه identity غیر قابل ویرایش است. به این دلیل که عموما این مقادیر static هستند و قرار نیست ویرایش بشن.

و مساله دیگری که نسبت به Update این خصیصه وجود داره این هست که عموما از این خصیصه برای کلید های اولیه در نظر گرفته میشه. خب با بروزرسانی این مقدار باید کل سطرهای فرزند نیز بروز رسانی بشه (اگر cascade referential integrity فعال باشه).

و اما راه اصولی. یک view بسازید که دارای یک ستون مرتب و sequential باشه و هر موقع که خواستین مقادیر متوالی و پشت سر هم را به عنوان row_id نشون بدین از این view استفاده کنید.
چیزی شبیه به این

CREATE VIEW view_name AS
SELECT ROW_NUMBER() OVER(ORDER BY identity_value) AS row_id, *
FROM table_name

پ.ن
راه های غیر اخلاقی مختلفی وجود داره که بتونید توسط آنها دائما مقدار id را sequential کنید اما بهتر بهش فکر نکنید چون شدیدا باعث اجرای تراکنش های اضافه شده و هزینه بر هستند.