السلام عليكم ورحمة الله وبركاته
السادة الكرام
لدي قاعدة بيانات1 فيها جدول1 بعمودين (id+name )
والعمود name مطلوب
و قاعدة بيانات2 فيها جدول2 بعمودين id+photo
اريد عندما اضيف سجل جديد في جدول1 ان يضاف نفس id في جدول2
بما أن العمود
name مطلوباً فإن اي خطأ يظهر عند الحفظ دون كتابة قيمة للحقل name فإنه يتم اضافة السجل للجدول2 في حين لم تتم اضافته للجدول1 وهنا الخطأ
الكود في BEFOREPOST للجدول1
كود :
if ABSTable1.State in [dsInsert] then
begin
ABSTable2.Append;
ABSTable2.FieldByName('ID').Value := ABSTable1.FieldByName('ID').Value;
ABSTable2.Post;
end;
وضعت في POST ERROR لتلافي الادخال في الجدول2
لكنه لم يعمل
كود :
if (E is EABSEngineError) then
begin
Showmessage('Error');
Abort;
end;
فكيف الحل؟؟[
attachment=4383]
السلام عليكم ورحمة الله وبركاته
هناك عدة حلول اولا ان تستخدام TRansction والتي تجعل من العمليتين ناجحتين او تلغي العمليتين
ثانيا يمكنك ان لا تضيف بالجدول الثاني الا بعد اضافة السجل الاول .بالجدول الاول اي تفعيل زر اضافة صورة للسجل بعد نجاح اضافة السجل
(09-11-2020, 04:33 PM)Delphi4Us كتب : [ -> ]ثانيا يمكنك ان لا تضيف بالجدول الثاني الا بعد اضافة السجل الاول .بالجدول الاول اي تفعيل زر اضافة صورة للسجل بعد نجاح اضافة السجل
نعم استاذي الكريم . نجحت هذه الطريقة.
لكن ماهو TRansction ؟
قد يختلف قليلا من قاعدة بيانات الى اخرى
كود :
dbDemos.StartTransaction;
try
AbsTable1.Insert;
AbsTable1.FieldByName('name').AsString := 'Kelly';
AbsTable1.Post;
AbsTable2.Insert;
AbsTable2.FieldByName('name').AsString := 'Kelly';
AbsTable2.Post;
dbDemos.Commit(cbFlush.Checked);
except
dbDemos.Rollback;
end;
كود :
with ABSQuery1 do
begin
SQL.Text := 'START TRANSACTION; INSERT INTO friends (name) values ("Junior");';
if cbFlush.Checked then
SQL.Text := SQL.Text + 'COMMIT;'
else
SQL.Text := SQL.Text + 'COMMIT NOFLUSH;';
try
ExecSQL;
except
SQL.Text := 'ROLLBACK';
ExecSQL;
end;
end;
(09-11-2020, 07:23 PM)Delphi4Us كتب : [ -> ]قد يختلف قليلا من قاعدة بيانات الى اخرى
كود :
dbDemos.Commit(cbFlush.Checked);
هذا الجزء لم يعمل عندي في absolute وحاولت تعديله فلم افلح
كل الشكر لك استاذي
قمت بعمل هذا الكود
فنجح الامر تماماً - اضافة-تعديل-حذف لكلا الجدولين . فهل يوجد افضل من ذلك؟
- جعلت في الجدول1 عمود auto اوتونمبر وبناء على قيمة الفريدة لهذا العمود سيتم الادخال في الجدول2 او التعديل او الحذف
كود :
procedure TForm1.ABSTable1AfterEdit(DataSet: TDataSet);
begin
label1.Caption := '1';
end;
procedure TForm1.ABSTable1AfterInsert(DataSet: TDataSet);
begin
label1.Caption := '0';
end;
procedure TForm1.ABSTable1AfterPost(DataSet: TDataSet);
begin
if label1.Caption = '0' then
begin
ABSTable2.Append;
ABSTable2.FieldByName('ID').Value := ABSTable1.FieldByName('ID').Value;
ABSTable2.FieldByName('auto').Value := ABSTable1.FieldByName('auto').Value;
ABSTable2.Post;
end;
if label1.Caption = '1' then
begin
With Qr1 Do
begin
Close;
SQL.Clear;
SQL.Add('Update Table2 Set ID = '+ InttoStr(ABSTable1ID.Value) +' Where auto = '+ IntToStr(ABSTable1auto.Value) +'');
ExecSQL;
ABSTable2.Refresh;
end;
end;
end;
procedure TForm1.ABSTable1BeforeDelete(DataSet: TDataSet);
begin
With Qr1 Do
begin
Close;
SQL.Clear;
SQL.Add('delete from table2 where auto = '+ inttostr(ABSTable1auto.Value) +'');
ExecSQL;
ABSTable2.Refresh;
end;
end;
procedure TForm1.ABSTable1PostError(DataSet: TDataSet; E: EDatabaseError;
var Action: TDataAction);
begin
if (E is EABSEngineError) then
begin
Showmessage('Error');
Abort;
end;
end;
لا احبذ طريقتك هذه لعدة اسباب
تصور ان يحدث خطاء في الادخال او اسثناء او حتى توقف الكمبيوتر لسبب ما او انقطعت الكهرباء اثناء القيام بالعملية الثانية المستخدم لا فرصة لديه لاعادة العملية لانها تحدث مرة واحدة فقط وهي عندما تضيف بيانات الجدول الاول ومرتبطة بهذا الحدث ، اما اذا كان الكود في في حدث زر يمكنه بعد عودة الكهرباء مثلا ان يكمل من حيث توقف او عندما يحدث خطاء مثل ادخال بيانات مكررة ان يعيد من حيث توقف لان كل شئ مرهون بنقرة زر .
وثانيا قاعدة البيانات التي ذكرتها تدعم الترنزساكشن transaction الذي ذكرناه فقط كما قلت لك قد تكون هناك اختلافات بسيطة هذه امثلة من موقع الشركة نفسها وهو الحل لطلبك والأمن لك من اي حوادث
كود :
drop table MyTable;
create table MyTable (ID AutoInc, val1 Integer, val2 string(10));
insert into MyTable (val1, val2) values (2,'Start');
start transaction;
insert into MyTable (val1, val2) values (4,'Rollback');
rollback;
start transaction;
insert into MyTable (val1, val2) values (5,'Commit');
commit;
select * from MyTable;
كود :
drop table MyTable;
create table MyTable (ID AutoInc, val1 Integer, val2 string(10));
insert into MyTable (val1, val2) values (2,'2');
insert into MyTable (val1, val2) values (4,'3');
start transaction;
insert into MyTable (val1, val2) values (5,'Flush1');
insert into MyTable (val1, val2) values (7,'Flush2');
commit flush;
select * from MyTable;
(10-11-2020, 11:58 PM)Delphi4Us كتب : [ -> ]اما اذا كان الكود في في حدث زر يمكنه بعد عودة الكهرباء مثلا ان يكمل من حيث توقف او عندما يحدث خطاء مثل ادخال بيانات مكررة ان يعيد من حيث توقف لان كل شئ مرهون بنقرة زر .
جزاك الله كل خير استاذي الكريم على الاهتمام والمشاركة
الا يمكن اعتبار حدث AfterPost كنقرة زر؟
على كل حال جربت كود الشركة كما ذكرت ونجح في الادخال
اما التعديل وهو الذي كان مشكلة لذلك اتبعت طريقة ال 0 و 1 للتمييز بين الحفظ بعد الادخال او التعديل
فكيف يكون ذلك؟
إقتباس :اما التعديل وهو الذي كان مشكلة لذلك اتبعت طريقة ال 0 و 1 للتمييز بين الحفظ بعد الادخال او التعديل
فكيف يكون ذلك؟
حسب مراجعة شفرتك السابقة يمكنك ان تعرف اذا كنت بوضع الاضافة او التعديل كالتالي:
كود :
if ABSTable1.State in [dsEdit] then
او
كود :
if ABSTable1.State in [dsInsert] then
(20-11-2020, 06:05 PM)Delphi4Us كتب : [ -> ]إقتباس :اما التعديل وهو الذي كان مشكلة لذلك اتبعت طريقة ال 0 و 1 للتمييز بين الحفظ بعد الادخال او التعديل
فكيف يكون ذلك؟
حسب مراجعة شفرتك السابقة يمكنك ان تعرف اذا كنت بوضع الاضافة او التعديل كالتالي:
كود :
if ABSTable1.State in [dsEdit] then
او
كود :
if ABSTable1.State in [dsInsert] then
المعذرة استاذي الكريم على التاخير في الرد
وضعت في حدث Afterpost للجدول الاول
كود :
dbdemo2.StartTransaction;
if ABSTable1.State in [dsInsert] then
BEGIN
try
AbsTable2.Insert;
ABSTable2.FieldByName('ID').Value := ABSTable1.FieldByName('ID').Value;
AbsTable2.Post;
dbdemo2.Commit(cbFlush.Checked);
except
dbdemo2.Rollback;
end;
end;
لكن ما هو الكود حال التعديل(في حال تغيير id من رقم 1 الى 11 مثلاً يجب تغيير id في الجدول الثاني ايضاَ من 1 الى 11 ) بدلالة اي شيئ؟؟