PDA

View Full Version : سوال: ارتباط بین جدول اوراکل و OracleDataAdapter



Saeed_m_Farid
چهارشنبه 28 مهر 1389, 15:02 عصر
سلام
من این سوال رو در بخش اوراکل پرسیدم (http://www.barnamenevis.org/forum/showthread.php?t=254542)، یک فکر دیگه هم به ذهنم رسید گفتم با شما مطرح کنم :
کلیت قضیه : یک جدولی داریم تو اوراکل که بزرگِ (دهها میلیون رکورد) برنامه های کلاینت من ازش باید رکورد بخونن و state رکوردهای خونده شده رو عوض کنند. وب سرویسی که به کلاینت ها سرویس میده در یک ترنزکشن اقدام به واکشی رکوردها از این جدول میکنه و تا اونجایی که من میدونم وقتی یکی از کلاینت ها در یک Transaction اقدام به SELECT از این جدول کرد، این مجموعه داده دیگه نباید برای سایر کلاینت ها قابل دستیابی باشه، یعنی اگه من 1000 تا رکورد رو انتخاب کنم تا وقتی کارم باهاشون تموم نشده (یعنی مثلاً State شون رو عوض نکردم) نباید یکی دیگه بتونه همون ها رو SELECT کنه، اگه تا اینجا فرضیاتم درست باشه:

سوالم اینه که من در یک Transaction اوراکلی! امکان داره بتونم از یک Select که حتماً باید براساس چند فیلد به ترتیب مرتب شده باشه، TOP بگیرم؟ (همونطورکه میدونید اوراکل TOP نداره و ROWID و ROWNUM داره که کاملاً کارکرد متفاوتی از TOP در MSSQL دارند.) مثلآً کاری مثل BulkRead که خودش یکی از فیلدها رو بعد خوندن SET کنه تا دیگر کلاینت ها اقدام به برداشتن اون نکنند، نکته مهم اینه که من نمیخوام همه رکوردها خونده بشه و بعد یک تعداد از اولش رو بردارم! باید یه تعاملی بین دات نت و اوراکل برقرار کنم تا تعداد محدودی از این جدول Fetch بشه به شرط ترتیب. موضوع دیگه هم این هست که طراحان نابغه این جدول یادشون رفته یک فیلد ID (دارای Sequence) به هر رکورد اختصاص بدن و روی دو تا از فیلدها Constraint بستن (یعنی کلید اصلی کردن شون) و من در آپدیت این رکوردها هم مصیبت عظمی میکشم!

وقتی صحبتی از Order نیست، WHERE ROWNUM < n+1 درست کار میکنه و n تا رکورد از اول جدول برمیگردونه، ولی وقتی Select رو Order By میکنم، اول Rownum روش اعمال میشه و بعد مرتب میکنه که مطمئناً این بدرد نمیخوره!

یک راه حل که به ذهنم رسید (و میدونم که خیلی زمانبر هست!) اینه که ROWNUM رو بیخیال بشم و کل جدول رو با شرط هام و ORDER BY مربوطه SELECT کنم و بعد OracleDataAdapter (مثلاً oda) که داره DataSet (مثلاً ds) رو پر میکنه، اینجوری عمل کنم :

oda.Fill(ds, 0, RECORD_COUNT, "MY_TABLE");
if (ds.Tables(0).Rows.Count > 0)
{
for (int i = 0; i <= ds.Tables(0).Rows.Count - 1; i++)
{
try {
VarRows = ds.Tables(0).Rows(i);
VarRows.BeginEdit();
VarRows.Item(1) = 1;
VarRows.Item(2) = MyDateTimeStamp;
VarRows.EndEdit();

} catch (Exception ex) {}
}
}
OracleCommandBuilder sqlobj = new OracleCommandBuilder(oda);
oda.Update(ds, "MY_TABLE");


خوب مشخصاً من فقط از شر query نوشتن واسه آپدیت راحت شدم، ولی بازم تمام رکورد ها رو SELECT میکنم :


SELECT Field1, Field2, Fieldn FROM MyTable
WHERE Field1=X AND Field2=Y AND Fieldn=Z
ORDER BY Field1 DESC, Field2, Fieldn DESC
راهی به ذهنتون میرسه؟ ممنون.

پ.ن.: آقا مهدی اگه به اون catch سریع توجهتون جلب شده، درستش میکنم، اصل قضیه حل بشه بعد ...

بطور مختصر، میخوام تعداد معینی از یک کوئری که از جدول بزرگی (اوراکل) گرفته میشه برداشته بشه، به دو شرط :

رکوردها مرتب شده باشند (قبل از محدود کردن تعداد، یا بعبارت دیگه اول مرتب شده باشند و بعد تعدادی از اونها برداشته شود.)
زمان کمتری از دیتابیس گرفته شود، یعنی تمام رکوردها بازیابی نشوند (که بسیار زمانبر هست) و فقط تعداد معینی رکورد برگردد (چیزی مثل Sorted Bulk!)

ممنون ...

mehdi.mousavi
دوشنبه 17 آبان 1389, 09:55 صبح
سلام سوالم اینه که من در یک Transaction اوراکلی! امکان داره بتونم از یک Select که حتماً باید براساس چند فیلد به ترتیب مرتب شده باشه، TOP بگیرم؟
پ.ن.: آقا مهدی اگه به اون catch سریع توجهتون جلب شده، درستش میکنم، اصل قضیه حل بشه بعد ...

سلام.
خوندن این مقاله (http://progcookbook.blogspot.com/2006/02/using-rownum-properly-for-pagination.html) به شما نشون میده که چطور ROWNUM رو پس از Sort کردن رکوردها روی اونها اعمال کنید. در نتیجه دیگه نیازی به استفاده از روشهای نامرسوم نیست.

موفق باشید.

پاورقی: دقیقا اون Catch توجه منو بخودش جلب کرد و در همون نگاه اول پیش خودم گفتم، "ما که قبلا در این مورد حرف زده بودیم!" بعدش که نوشته آبی رنگ رو دیدم، دوباره آرامش بهم برگشت. :) در هر حال، ممنون میشم سوال خودتون رو از بخش Oracle حذف کنید.