ورود

View Full Version : سوال: CRecordset::GetRecordCount



Cave_Man
جمعه 18 بهمن 1387, 00:59 صبح
با سلام
من با استفاده از کلاس های CDataBase و CRecordser یه دیتابیس رو باز میکنم اما با استفاده از دستور GetRecordSet فقط میتونم عدد یک رو بگیرم یعنی Recordset تنها یک رکورد رو برمیگردونه.
فکر میکنید مشکل از کجاست؟
قطعه کدی رو هم که استفاده میکنم اینه:


CDatabase db;
db.OpenEx( _T("DSN=AccountingCA;UID=SA;"), CDatabase::noOdbcDialog);

CRecordset rs( &db );
rs.Open( CRecordset::forwardOnly, //execute the SQL received from client and catch informatio into RecordSet
_T( SQL ));

long recCount=0;
recCount=rs.GetRecordCount();

Nima_NF
شنبه 19 بهمن 1387, 00:09 صبح
متوجه نشدم منظورتان از کد زیر چی هست؟



_T( SQL ));


اگر می خواهید یک سری چیز بگیرید باید دستور SQL بنویسید یا CALL و ... مثلا SELECT :



_T( "Select name from students" ) );

Cave_Man
شنبه 19 بهمن 1387, 09:55 صبح
اون SQL یک TCHAR هست و حاوی دستورات SQL که باید اجرا بشود.
مثلا حاوی رشته ی "SELECT * FROM Table1" هست.
مشکل اینجاست که وقتی Recordset ایجاد و باز میشه، تابع GetRecordCount عدد یک رو برمیگردونه در حالی که دیتابیس و جدول ما ، بیش از یک رکورد داره.

آقا نیمای گل منظورتون از CALL چی هست؟

Nima_NF
شنبه 19 بهمن 1387, 14:32 عصر
اگر قرار هست از یک رشته TCHAR استفاده کنید فقط نام آن را باید در پارامتر دوم بنویسید، _T در موقعی هست که می خواهید مستقیم رشته ای را در جایی بنویسید تا با توجه به تنظیمات کامپایلر آن را یونیکد یا اسکی در نظر بگیرد.


برای اینکه متوجه شوید آیا خطایی در کارهایتان انجام داده اید یا نه سعی کنید سایر فلگ ها و Option ها را نیز امتحان کنید مثلا پیش فرض را:



TCHAR strSQL = _T("SELECT * FROM Table1");
rs.Open(AFX_DB_USE_DEFAULT_TYPE, strSQL);


همین طور سایر موارد مانند CRecordset::snapshot و غیره.


منظورتون از CALL چی هست؟
store procedure، برای دیدن توضیحات و موارد دیگر، MSDN را برای پارامتر lpszSQL در open برای همین کلاس مشاهده کنید.

Cave_Man
دوشنبه 21 بهمن 1387, 01:26 صبح
با تشکر از توضیحات ارزشمند آقا نیما
خیلی عجیبه که MSDN برخی جاها اطلاعات ناقص و بعضا اشتباهی رو در اختیار ما قرار میده.
اما حقیقت در مورد تابع GetRecordCount چی هست... حقیقت اینه که این تابع تعداد رکورد دیتاست رو برنمیگردونه بلکه تعداد رکورد پیمایش شده در رکوردست رو برمیگردونه..به این ترتیب هر وقت شما یه رکورد ست رو باز کنید GetRecordCount یا مقدار صفر داره ( به این معنی که رکوردست هیچ رکوردی توش نیست) و یا مقدار یک داره یعنی اینکه رکوردست حداقل یک رکورد داره...حالا اگه شما در این رکوردست با استفاده از دستوراتی مثل MoveNext پیشمایش کنید ...مقدار برگشتی از تابع GetRecordCount افزایش پیدا میکنه.

این از اشتباهات متداول در کلاس CRecordset هست.

اما راه چاره چی هست؟ چگونه میتوان تعداد رکورد هایی رو که لازم داریم بدست بیاریم.برای این کار دوراه وجود داره:
اول اینکه آنقدر MoveNext کنیم تا به انتهای رکورد های برسیم و بعد تابع GetRecordCount رو فراخونی کنیم
دوم اینکه با استفاده از یک دستور SQL تعداد رکورد هایی رو که لازم داریم بدست بیاریم..منظور از دستور اس کیو ال همون دستور SELECT COUNT(*) FROM Table1 هست.با چیزی شبیه به این.

روش اول از نظر کارایی با مشکل بزرگی روبه رو هست.این روش در جداول با تعداد رکورد زیاد از کارایی خیلی پایینی برخوداره.
روش دوم از نظر کارایی بسیار عالی عمل میکنه و در کسری از ثانیه میتونیم تعداد رکورد ها رو شناسایی کنیم.

Nima_NF
دوشنبه 21 بهمن 1387, 12:57 عصر
خیلی عجیبه که MSDN برخی جاها اطلاعات ناقص و بعضا اشتباهی رو در اختیار ما قرار میده.

نمر دانم شما از چه نسخه MSDN استفاده می کنید ولی معمولا این خواننده است که از مطالب اشتباه برداشت می کند یا قبل از استفاده آن را درست مطالعه نمی کند. همیشه برای هر تابعی باید نوشته های مربروط به آن را دقیق مطالعه کنید.

مثلا در مورد GetRecordCount به این شکل نوشته شده است:




Caution

The record count is maintained as a "high water mark," the highest-numbered record yet seen as the user moves through the records. The total number of records is only known after the user has moved beyond the last record. For performance reasons, the count is not updated when you call MoveLast. To count the records yourself, call MoveNext repeatedly until IsEOF returns nonzero. Adding a record via CRecordset:AddNew and Update increases the count; deleting a record via CRecordset::Delete decreases the count.



که این امر نیز جهت افرایش کارآیی ذکر شده است.

Cave_Man
سه شنبه 22 بهمن 1387, 12:26 عصر
بله من قسمت Caution رو نخونده بودم..اما همین روشی که گفته یعنی MoveNext تا زمانی که IsEOF یک مقدار nonZero برگردونه از نظر کارایی با چالش روبرو هست..طبق پست قبلی.
خیلی ممنون که تذکر دادین آقا نیمای عزیز.
منظور من این قسمت بود که توضیح مبهمی داره:


Return Value

The number of records in the recordset; 0 if the recordset contains no records; or –1 if the record count cannot be determined.