View Full Version : مشکلات Midas : حذف رکورد
MNosouhi
چهارشنبه 29 آذر 1385, 18:53 عصر
در هنگام حذف رکوردی از یک جدول که در جدول دیگه مورد استفاده قرار گرفته(حالت lookup، که در این حالت نباید اجازه حذف بده،چون تا وقتی وابسته هست نباید رکورد پدر حذف بشه) ، رکورد از clientdataset حذف میشه (که نباید حذف بشه) ، البته با refesh کردن دوباره رکورد حذف شده رو نشون میده ، اما اینطوری باید بعد از هر حذفی که درست انجام نمیشه ، یک بار Refresh کرد.
دستور CancelUpdate و رویداد OnReconcileError هم نمیتونه تاثیری در نتیجه بزاره.
البته این مشکل زمانی پیش میاد که در سمت سرور از adoQuery استفاده کرده باشیم یا از AdoDataSet استفاده کرده باشیم و Commandtype را روی CmdText گذاشته باشیم.
پس باید چکار کرد که وقتی مشکلی در حذف پیش میاد داخل clientdataset رکورد حذف نشه؟
soroush_vs
چهارشنبه 29 آذر 1385, 20:30 عصر
من فکر میکنم به خاطر UnDirect بودن ClientDataSet در این معماری شما میتونید حذف رو انجام بدید.ولی اگر نظر من رو بخاید از LookUp استفاده نکنید.لطفا اساتید سایت نظر خودشون رو درباره LookUp بدن استفاده کنیم.
تشکر
vcldeveloper
پنج شنبه 30 آذر 1385, 08:10 صبح
به خاطر UnDirect بودن ClientDataSet
یعنی چی؟!!
حرفه ای
پنج شنبه 30 آذر 1385, 09:12 صبح
اول بانکها رو اگه داخل دیتابیس relation کنی با حذف یک master سایر detail های متعلقه نیز حذف میشه یا در بانک detail جستجو کن اگه اطلاعات نبود بعد عملیات حذف رو انجام بده
MNosouhi
پنج شنبه 30 آذر 1385, 09:27 صبح
اول بانکها رو اگه داخل دیتابیس relation کنی با حذف یک master سایر detail های متعلقه نیز حذف میشه یا در بانک detail جستجو کن اگه اطلاعات نبود بعد عملیات حذف رو انجام بده
اینکار طول میکشه و از طرفی خود sql آن را مدیریت می کند . لازم نیست خودم اینکار رو بکنم.
ببینید وقتی Commandtype را روی CmdTable قرار بدم ، با CancelUpdate قضیه حل میشه ، اما وقتی Commandtype را روی CmdText قرار می دم این مشکلی که گفتم بوجود میاد و CancelUpdate هم کاری از پیش نمی بره.
soroush_vs
پنج شنبه 30 آذر 1385, 10:30 صبح
یعنی چی؟!!
یعنی CleintDataset بطور مستقیم به دیتابیس متصل نیست و عملیات در یک حافظه موقتی انجام میشود نا اینکه فرمان ApplyUpdates اجرا شود.اینها رو شما که بهتر از من میدونید.
اما بیایید این اشکال رو به Midas نسبت ندهیم چون اولا ClientDataSet رو نمیتونیم اختصاصی برای Midas در نظر بگیریم و ثانیا ClientDataSet این خصوصیات رو از کلاس های بالا تری خود به ارث میبرد بنابراین این اشکال را به کلاس TDataSet نسبت دهیم البته اگر واقعا بتوان اسمش را اشکال گذاشت.چون ClientDataSet حذف را بصورت موقتی انجام میدهد اما اگر ApplyUpdates را فراخوانی کنیم قائدتا باید خطا صادر شود.
vcldeveloper
شنبه 02 دی 1385, 09:19 صبح
یعنی CleintDataset بطور مستقیم به دیتابیس متصل نیست و عملیات در یک حافظه موقتی انجام میشود نا اینکه فرمان ApplyUpdates اجرا شود.اینها رو شما که بهتر از من میدونید.
مسئله اینه که به این ویژگی unidirect نمیگن. البته اصلا چیزی به اسم unidriect وجود نداره. در زبان انگلیسی indirect استفاده میشه.
در هنگام حذف رکوردی از یک جدول که در جدول دیگه مورد استفاده قرار گرفته(حالت lookup، که در این حالت نباید اجازه حذف بده،چون تا وقتی وابسته هست نباید رکورد پدر حذف بشه) ، رکورد از clientdataset حذف میشه (که نباید حذف بشه)
شما انتظار دارید ClientDataSet خودش متوجه وابسته بودن داده های یک جدول به جدول دیگه بشه و مانع از حذف داده های اون جدول بشه؟! اگر قرار نیست داده ها تغییر داده بشند، ClientDataSet را ReadOnly کنید. اگر جداول به هم وابستگی دارند، وابستگی را در سمت پایگاه داده تعریف کنید.
البته با refesh کردن دوباره رکورد حذف شده رو نشون میده ، اما اینطوری باید بعد از هر حذفی که درست انجام نمیشه ، یک بار Refresh کرد.
همونطور که دوستان گفتند، ClientDataSet و سایر مشتقات DataSet یک جدول محلی در سمت client میسارند که داده های گرفته شده از سرور در اون نگه داری میشه. تغییر در این داده ها موجب تغییر در داد های سمت سرور میشه. در صورت استفاده از حالت batch update، تغییرات تا زمان فراخوانی متد ApplyUpdate به سرور منتقل نمیشند. علت حذف نشدن اون رکوردها هم همینه که متد ApplyUpdate فرخوانی نشده.
MNosouhi
شنبه 02 دی 1385, 10:03 صبح
ممنون از جوابتون.
شما انتظار دارید ClientDataSet خودش متوجه وابسته بودن داده های یک جدول به جدول دیگه بشه و مانع از حذف داده های اون جدول بشه؟!
نه من این انتظار رو ندارم ، ببینید من فقط یک دستور delete استفاده می کنم ، حالا وقتی applyUpdate می کنم ، رویداد OnReconcileError اجرا میشه ، چون همون دستور delete رو نمی تونه روی دیتابیس انجام بده ، قائدتا باید با دستور cancelUpdate رکوردی رو که قبلا از داخل clientdataset حذف شده رو برگردونه ، اما این کار رو نمی کنه . همونطوری که گفتم ، اگه از adotable استفاده کنم یا در AdoDataset خصوصیت commandtype رو روی cmdtable قرار بدم ، دستوز cancelupdate رکورد رو بر می گردونه و مشکلی نیست. این مشکل فقط زمانی پیش میاد که از adoquery استفاده کرده باشم و commandtype روی cmdtext باشه.
همونطور که دوستان گفتند، ClientDataSet و سایر مشتقات DataSet یک جدول محلی در سمت client میسارند که داده های گرفته شده از سرور در اون نگه داری میشه. تغییر در این داده ها موجب تغییر در داد های سمت سرور میشه. در صورت استفاده از حالت batch update، تغییرات تا زمان فراخوانی متد ApplyUpdate به سرور منتقل نمیشند. علت حذف نشدن اون رکوردها هم همینه که متد ApplyUpdate فرخوانی نشده.
منظورم رو متوجه نشدید ، فکر کنم من بد توضیح دادم.
MNosouhi
شنبه 02 دی 1385, 23:47 عصر
آخرش یه راه حل پیدا کردم ، درسته که باز هم بهینه نیست ، اما حداقلش اینه که کاری به سرور نداره :
var TypePost:UTTypeSaveRecords;
cds:TClientDataSet;
BookMark:TBookmarkStr;
..............
cds:=TClientDataSet.Create(nil);
cds.Data:=ClientDataSet.Data;
BookMark:=ClientDataSet.Bookmark;
ClientDataSet.Delete;
if ClientDataSet.ApplyUpdates(-1)> 0 then
begin
ClientDataSet.CancelUpdates;
ClientDataSet.Data:=cds.Data;
ClientDataSet.Bookmark:=BookMark;
cds.Free;
end
else
cds.Free;امیدوارم بدرد بقیه هم بخوره.
اما هنوز مشکل insert مونده.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.