ورود

View Full Version : بدست آوردن مقدار identity که قراره در جدول قرار بگیره



maktab
دوشنبه 10 بهمن 1390, 10:50 صبح
سلام
من در جدولم یک فیلد بصورت identity معرفی کردم. حالا میخوام مقدار آخرین فیلد جدید (یعنی فیلدی که قراره در جدول قرار بگیره) را بدست بیارم. توی سایت سرچ کردم این دستور را پیدا کردم:


SELECT @@IDENTITY('NameTable')

ولی این کد، مقدار آخرین فیلد موجود در جدول را نشان میده. در صورتی که من مقدار آخرین فیلدی که قراره در بانک قرار بگیره را بدست بیارم.

shahab2025
دوشنبه 10 بهمن 1390, 14:28 عصر
سلام
خوب این چیزی را که به دست میاری به اضافه یک کن ....

in_chand_nafar
دوشنبه 10 بهمن 1390, 16:13 عصر
بهترین کار این که اگه می خواهی اون رو به کاربر نشون بدی بعد ذخیره کردن اون را با تابع ذکر شده بدست بیاری و به کاربر نشون بدی در ضمن نمی تونی
(من مقدار آخرین فیلدی که قراره در بانک قرار بگیره را بدست بیارم. ) اینی که میگه رو با این تابع به راحتی انجام بدی تحت شبکه بودن برنامه و کاربرهای دیگه رو در نظر بگیر سناریو خودت رو تشریح کن تا راه حل مناسب بگیری

tiphooo
دوشنبه 10 بهمن 1390, 18:38 عصر
این کار به راحتی و با استفاده از trigger قابل انجام است . اگر بخواهی آخرین مقدار را بدست آورده و با عدد یک جمع کنی در صورتی که این کار بعد از چند حذف و اضافه انجام بگیرد مقدار بدست آمده درست نخواهد بود . فرضا شماره آخرین رکورد 1000 بوده و سپس شما این رکورد را حذف کن حالا آخرین شماره باقی مانده 999 خواهد بود در حالی که اگر الان در جدول رکوردی درج شود شماره 1001 را بخود خواهد گرفت نه 999+1 (به خاطر Identity بودن فیلد).
اما در Trigger حالتهای FOR,AFTER وجود دارد و حالت FOR INSERT همان زمان درج است و هنوز درج صورت نگرفته و شما می توانی اینجا مقدار را گرفته و جاهای دیگر استفاده کنی

maktab
دوشنبه 10 بهمن 1390, 22:37 عصر
این کار به راحتی و با استفاده از trigger قابل انجام است .
ممنون. دقیقا به چنین چیزی نیاز دارم.
اگر میشه با یه نمونه کد توضیح بدید.

tiphooo
سه شنبه 11 بهمن 1390, 01:21 صبح
CREATE TRIGGER [dbo].[تريگر نام] ON [dbo].[جدول نام]
FOR INSERT
NOT FOR REPLICATION AS
DECLARE @ID int
SELECT @ID = Id
FROM INSERTED

@ID در اینجا متغیر
شما Identity مقدار
که قرار است درج شود در خود دارد وشما مثلا می توانید این مقدار را به پروسیجری انتقال دهید و هر کاری که می خواهید با آن انجام دهید و یا همینجا هر کاری می خواهید با ان انجام دهید فقط اینکه شما نمی توانید این مقدار را تغییر دهید .قاعدتا شما باید در جدول فیلدی با نام Id داشته باشید که Identity باشد

END

maktab
سه شنبه 11 بهمن 1390, 21:14 عصر
CREATE TRIGGER [dbo].[تريگر نام] ON [dbo].[جدول نام]
FOR INSERT
NOT FOR REPLICATION AS
DECLARE @ID int
SELECT @ID = Id
FROM INSERTED

@ID در اینجا متغیر
شما Identity مقدار
که قرار است درج شود در خود دارد وشما مثلا می توانید این مقدار را به پروسیجری انتقال دهید و هر کاری که می خواهید با آن انجام دهید و یا همینجا هر کاری می خواهید با ان انجام دهید فقط اینکه شما نمی توانید این مقدار را تغییر دهید .قاعدتا شما باید در جدول فیلدی با نام Id داشته باشید که Identity باشد

END


من استفاده کردم ولی هیچگونه اطلاعاتی بعنوان خروجی نداد! من تا حالا با TRIGGER کار نکردم. به جای Id نام فیلد Identity رو نوشتم. ولی بعد از اجرا یه TRIGGER درست کرد ولی خروجی نداشت.
اگر میشه بیشتر راهنمایی کنید.
راستی میتوان همین کار را با linq در داخل برنامه انجام داد؟

tiphooo
چهارشنبه 12 بهمن 1390, 02:14 صبح
تریگر خروجی نداره و شما مقدار Identity ;که اینجا در یک متغیر ریختید می توانید به یک پروسیجر پاس داده و خروجیهای لازم را انجا کسب کنید . شما که با تریگر کار نکردید باید بگویم به شکل دیگری باید به قضیه نگاه کنید و مثلا یک دستور select که می نویسید و نتیجه آن معمولا چند رکورد است کار تریگر حالت عملیاتی است نه پرس و جو.و شما نمی توانید اسم یک تریگر را مانند یک پروسیجر و یا تابع در جاهای دیگر فراخوانی کنید.
در مورد LinQ هم من اطلاعات کافی ندارم.

اوبالیت به بو
جمعه 14 بهمن 1390, 11:52 صبح
درود

من همیشه از این روش استفاده می کنم:



set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER Procedure [dbo].[sp_Patients_Insert]
@Date datetime = NULL,
@FullyName nvarchar(50) = NULL,
@Mobile nvarchar(50) = NULL,
@Telephone nvarchar(50) = NULL,
@Address nvarchar(500) = NULL,
@Descriptions nvarchar(1000) = NULL,
@UserID int
As
Begin
Insert Into Patients
([Date],[FullyName],[Mobile],[Telephone],[Address],[Descriptions],[UserID])
Values
(@Date,@FullyName,@Mobile,@Telephone,@Address,@Des criptions,@UserID)

SELECT SCOPE_IDENTITY()
End


زمانیکه من هم بدنبال یک راه حل برای این کار می گشتم تو اکثر وبلاگ ها توصیه شده بود از روش @@IDENTITY استفاده نکنید و از Select SCOP_Identity() استفاده بشه.

maktab
جمعه 14 بهمن 1390, 12:43 عصر
درود

من همیشه از این روش استفاده می کنم:



set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

ALTER Procedure [dbo].[sp_Patients_Insert]
@Date datetime = NULL,
@FullyName nvarchar(50) = NULL,
@Mobile nvarchar(50) = NULL,
@Telephone nvarchar(50) = NULL,
@Address nvarchar(500) = NULL,
@Descriptions nvarchar(1000) = NULL,
@UserID int
As
Begin
Insert Into Patients
([Date],[FullyName],[Mobile],[Telephone],[Address],[Descriptions],[UserID])
Values
(@Date,@FullyName,@Mobile,@Telephone,@Address,@Des criptions,@UserID)

SELECT SCOPE_IDENTITY()
End


زمانیکه من هم بدنبال یک راه حل برای این کار می گشتم تو اکثر وبلاگ ها توصیه شده بود از روش @@IDENTITY استفاده نکنید و از Select SCOP_Identity() استفاده بشه.

اگر ممکنه در مورد روشی که گفتید توضیح بدید. ممنون از شما

tiphooo
جمعه 14 بهمن 1390, 13:37 عصر
() SCOPE_IDENTITY اخرین مقدار درج شده بعد از اینکه عملیات درج انجام شد می دهد و برای جداول مختلف تفاوتی نمی کند حال اینکه تصور من این بود که قبل از اینکه عملیات درج در جدول کامل شود شما نیاز به ID درج شده دارید در غیر اینصورت این تابع کار شما را راه می اندازد و نیاز به استفاده از تریگر نیست .

Galawij
جمعه 14 بهمن 1390, 13:46 عصر
حال اینکه تصور من این بود که قبل از اینکه عملیات درج در جدول کامل شود شما نیاز به ID درج شده دارید
من هم فکر می کنم سوالشون همین بود!
ولی در هر صورت پست شماره 5 این لینک (http://barnamenevis.org/showthread.php?297602-%DA%86%D9%86%D8%AF-%D8%B3%D9%88%D8%A7%D9%84-%D8%AF%D8%B1-%D9%85%D9%88%D8%B1%D8%AF-Sql-server&highlight=%DA%86%D9%86%D8%AF+%D8%B3%D9%88%D8%A7%D9 %84) را ببینید، امیدوارم بهتون کمک کنه.

اوبالیت به بو
جمعه 14 بهمن 1390, 14:14 عصر
اگر ممکنه در مورد روشی که گفتید توضیح بدید. ممنون از شما

حتما.

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

روش های مختلفی هست مثلا یک نفر بوسیله Select Max(ID) FROM tbl میومد آخرین رو پیدا می کرد و روش های مختلف دیگه ....

شما با اضافه کردن دستور SELECT SCOPE_IDENTITY() در انتهای پراسیجر مربوط به Insert می تونید مقداری که همون لحظه توسط سیستم تولید شده رو دریافت کنید. اگر در C# برنامه نویسی می کنید برای اجرای این دستور باید از دستور ExecuteScaler استفاده کنید و اون رو به int تبدیل کنید.

baktash.n81@gmail.com
شنبه 15 بهمن 1390, 08:10 صبح
سلام

در خصوص @@Identity که Scope_Identity اشتباه فکر نکنید ... این متغیر و تابع فقط زمانی که عمل Insert انجام شده باشه مقدار می گیرند ... نمی تونید از روی اینها قبل از عمل Insert مقداری رو بدست بیارید.

اما یه تابع هست به اسم Ident_Current('TableName') که می تونی با اجرای اون بفهمی آخرین مقدار Identity چقدره و اونو با یک جمع کنی ... و البته بعد از حذف کردن آخرین رکورد و اینجور چیزا که دوستمون اشاره کرد مشکلی پیش نمیاد. چون این تابع دقیقا به مقدار Identity نگاه می کنه نه آخرین رکورد جدول.

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

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

baktash.n81@gmail.com
شنبه 15 بهمن 1390, 08:15 صبح
روش Select Max رو کلا فراموش کنید ...