PDA

View Full Version : برگرشت آخرین رکورد



binyaz2003
سه شنبه 05 آبان 1383, 10:29 صبح
با سلام
چطور دستور select بنویسم که آخرین رکورد موجود رو برگردونه فقط آخرین!

AminSobati
سه شنبه 05 آبان 1383, 11:58 صبح
دوست عزیزم،
اگر جدول شما دارای فیلد IDENTITY هستش، طبیعتا هر رکوردی که وارد میشه، بالاترین مقدار رو خواهد داشت که میتونین بوسیله IDENT_CURRENT یا IDENTITY@@ یا حتی گرفتن ()MAX، مقدارش رو بدست بیارین و بعد در Query، از این مقدار در WHERE استفاده کنین تا رکورد مورد نظر بدست بیاد.
اما اگر فیلد IDENTITY ندارین، بفرمایید تا اون روش رو توضیح بدم.
موفق باشین

binyaz2003
سه شنبه 05 آبان 1383, 18:53 عصر
سلام
نداره؟ :گیج:

AminSobati
سه شنبه 05 آبان 1383, 23:19 عصر
دوست عزیزم،
اگر جدول شما مطلقا ایندکس نداره، میتونین از این تکنیک استفاده کنین: SELECT بدون WHERE!
در این حالت SQL Server تمام جدول رو Scan میکنه و آخرین رکورد در متغیرهای تعریف شده باقی میمونه:

DECLARE @Col1 INT
DECLARE @Col2 INT

SELECT @Col1=Field1, @Col2=Field2 FROM MyTable
SELECT @Col1, @Col2
علت اینکه تاکید کردم هیچ ایندکسی وجود نداشته باشه اینه که SQL Server مجبور میشه Pageهای خود جدول رو Scan کنه. ولی اگر ایندکس وجود داشته باشه، ممکنه تشخیص بده که Scan از روی یک ایندکس خاص، سریعتر انجام میشه و اون رو انتخاب کنه. اما اطلاعات در ایندکس، مرتب شده هستن و ترتیب رکوردها متفاوته با اون چیزی که موقع Data Entry وجود داشته. به عنوان مثال من همین تکنیک رو روی جدول Customers در دیتابیس Northwind دو بار انجام میدم ولی SQL Server رو راهنمایی میکنم تا از روی ایندکس دلخواه من Scan انجام بده. میبینیم که رکورد برگردونده شده متفاوت خواهد بود:

DECLARE @CID CHAR(5)
DECLARE @CNT VARCHAR(30)

SELECT @CID=CustomerID, @CNT=Country FROM Customers WITH (INDEX(PK_Customers))
SELECT @CID, @CNT
حالا در مرتبه دوم:

DECLARE @CID CHAR(5)
DECLARE @CNT VARCHAR(30)

SELECT @CID=CustomerID, @CNT=Country FROM Customers WITH (INDEX(PostalCode))
SELECT @CID, @CNT
نتیجه باید متفاوت باشه!

اما اگر جدول شما ایندکس Clustered نداره و فقط nonClustered داره(یعنی اصل جدول Sort نشده)، هنوز از روش بالا میتونین استفاده کنین به شرط اینکه SQL Server رو راهنمایی کنین تا از هیچ ایندکسی استفاده نکنه (یعنی به جای نام ایندکس، مقدار 0 رو قرار بدین). البته در جدول Customers چون ایندکس Clustered وجود داره و جدول واقعا مرتب شده، باز هم استفاده از 0 همون نتیجه PK_Customers رو خواهد داشت.

اگر ایندکس Clustered وجود داشته باشه و نتونیم از روش گفته شده استفاده کنیم، یک روش دیگه وجود داره:
یک فیلد از جنس DateTime اضافه کنیم و برای مقدار Default از تابع GetDate استفاده کنیم. چون زمان با دقت هزارم ثانیه در این فیلد قرار میگیره، حتی اگر دو رکورد، همزمان Insert بشن، باز در هزارم ثانیه متفاوت خواهند بود(با کنترل Transaction Isolation Level میتونین یقین کنید که دو رکورد هیچ وقت دقیقا همزمان وارد نمیشن). پس اگر MAX این فیلد رو بگیرین، جدیدترین رکورد رو میتونین بدست بیارین.
موفق باشین