PDA

View Full Version : نوشتن اطلاعات به صورت همزمان در دو جدول



baranbahari1320
پنج شنبه 03 دی 1394, 16:55 عصر
با سلام
من دوتا جدول دارم که هر کدوم شامل یکسری اطلاعات هستش و با هم در ارتباطن حالا میخوام تو سی شارپ یه کوری بنویسم که به صورت همزمان وقتی که مثلا کاربر به عنوان دانشجو میخواد ثبت نام کنه یا استاد اطلاعات رو بگیره ولی در دو جدول مجزا مثلا جدول مریوط به کد کاربری و رمز عبور و بقیه اطلاعات هم در جدول استاد یا دانشجو باشه.
میخوام ببینم به جز تریگر روش دیگه ای هم هست البته من تا حالا با trigger هم کار نکردم اگه یه نمونه برام بذارین که ببینم بعد از ایجاد تریگر در sql server چطور ازش در c# استفاده می کنن ممنون میشم.
خیلی ضروریه.

Mahmoud.Afrad
پنج شنبه 03 دی 1394, 18:01 عصر
اگر اطلاعات به هم وابسته هستند و در صورت عدم درج در جدول اول در جدول دوم هم درجی نباید صورت بگیره باید در یک transaction ایجاد رو انجام بدید.
ذخیره شدن اطلاعات در جدول دوم به شرط درج شدن در جدول اول (http://barnamenevis.org/showthread.php?426018-%D8%B0%D8%AE%DB%8C%D8%B1%D9%87-%D8%B4%D8%AF%D9%86-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA-%D8%AF%D8%B1-%D8%AC%D8%AF%D9%88%D9%84-%D8%AF%D9%88%D9%85-%D8%A8%D9%87-%D8%B4%D8%B1%D8%B7-%D8%AF%D8%B1%D8%AC-%D8%B4%D8%AF%D9%86-%D8%AF%D8%B1-%D8%AC%D8%AF%D9%88%D9%84-%D8%A7%D9%88%D9%84)

transeaction های linq to sql (http://barnamenevis.org/showthread.php?385939-transeaction-%D9%87%D8%A7%DB%8C-linq-to-sql)

baranbahari1320
دوشنبه 14 دی 1394, 16:42 عصر
ممنون از راهنماییتون
.لی من اصلا متوجه نشدم که باید چطور transaction رو برای دو جدولم بنویسم
من میخوام برای اضافه کردن کتاب به لیست کتابهای کتابخانه همزمان بتونم اطلاعات کتاب مثل نام کتاب،کد کتاب وتعداد رو به جدول کتاب و نام ناشر رو به جدول ناشر اضافه کنم دو جدول هم با کد ناشر با هم در ارتباطند حالا با transaction چزور باید دستور insert رو بنویسم.تو سایتهای زبان اصلی هم خیلی جستجو کردم چیز زیادی دستگیرم نشد.

Mahmoud.Afrad
سه شنبه 15 دی 1394, 10:44 صبح
از چه روشی برای درج استفاده میکنی؟ LinqToSql ، entity framework یا ado.net ؟

baranbahari1320
سه شنبه 15 دی 1394, 23:30 عصر
از روش ado.net

Mahmoud.Afrad
چهارشنبه 16 دی 1394, 13:32 عصر
توسط متد BeginTransaction از شئ کانکشن یک تراکنش ایجاد کنید و به تراکنش کامند نسبت بدید. (کانکشن باید قبلا open شده باشه)
تمام اعمال درج که به هم وابسته هستند رو انجام بدید. و بعد تراکنش رو Commit کنید. (برای بدست آوردن ID درج شده در جدول اول از فانکشن SCOPE_IDENTITY در کد sql استفاده کنید و سپس این مقدار رو در جدول دوم به عنوان کلیدخارجی درج کنید)
اگر در عمل درج در دیتابیس خطایی رخ داد تراکنش رو Rollback کنید.
مثال:

SqlCommand command = new SqlCommand {Connection = _connection};
if (_connection.State != ConnectionState.Open)
{
_connection.Open();
}
command.Transaction = _connection.BeginTransaction();
try
{
command.CommandText =
"insert into person(firstname, lastname) values(@fname, @lname);" +
"declare @p as int = (select SCOPE_IDENTITY());";
command.Parameters.AddWithValue("@Fname", txtFirstName.Text);
command.Parameters.AddWithValue("@Lname", txtLastName.Text);

for (int i = 0; i < listBox1.Items.Count; i++)
{
SqlParameter parameter = new SqlParameter("@phonNumber" + i, SqlDbType.VarChar)
{
Value = listBox1.Items[i]
};
command.CommandText += string.Format("insert into phone(phoneNumber, personId) values({0} , @p);", parameter.ParameterName);
command.Parameters.Add(parameter);
}

command.ExecuteNonQuery();
command.Transaction.Commit();
}
catch (Exception exception)
{
command.Transaction.Rollback();
MessageBox.Show(exception.Message);
}
finally
{
if (_connection != null) _connection.Dispose();
if (command != null) command.Dispose();
}

baranbahari1320
چهارشنبه 16 دی 1394, 17:39 عصر
ممنون از راهنمایتون.فقط اگه درست متوجه شده باشم ID جدول که فرمودین باید به صورت خودکار پر بشه که در اون صورت میتوان مقدار اون رو همزمان با عمل درج بیرون کشید

برای بدست آوردن ID درج شده در جدول اول از فانکشن SCOPE_IDENTITY در کد sql استفاده کنید و سپس این مقدار رو در جدول دوم به عنوان کلیدخارجی درج کنید
ولی من وقتی میخوام مشخصات یک کتاب رو اضافه کنم توسط یه فرم اطلاعات کتاب رو در جدول کتاب و اطلاعات ناشر رو در جدول ناشر و کد ناشر همزمان توسط خود مدیر در هر دو جدول باید درج شود به صورت دستی.
تعریف کد های زیر در کلاس Access برای دسترسی کل پروژه

public DataAccess()
{
scon = new SqlConnection();
scom = new SqlCommand();
sda = new SqlDataAdapter();
scom.Connection = scon;//ارتباط با پایگاه داده از طریق خصوصیت connection برای انجام انواع عملیات
sda.SelectCommand = scom;//از خصوصیت select commend مربوط به dataadaptor برای انجام عملیات select استفاده می شود.

}
public void connect()//متدی برای اتصال به پایگاه داده
{
scon.ConnectionString = "Server=(local);database=library;Integrated Security=true;";//استفاده از رشته connection string در کلاس sqlconnection;
scon.Open();//متد openرای باز کردن ارتباط با پایگاه



}
public void insert1(string Sql1,string Sql2)
{
scom.Connection = scon;
/*if (scon.State != ConnectionState.Open)
{
scon.Open();
}*/
scom.Transaction = scon.BeginTransaction();
try
{
scom.CommandText = Sql1;

scom.CommandText = Sql2;


scom.ExecuteNonQuery();
scom.Transaction.Commit();
}
/* catch (Exception exception)
{
scom.Transaction.Rollback();
// messagebox .Show(exception.Message);
}*/
finally
{
if (scon != null) scon.Dispose();
if (scom != null) scom.Dispose();
}
}

}



و نوشتن دستورات sql برای درج در کلاس book بر اساس transaction

public void Add()
{
string Sql1 = "insert into book(bid,gid,pid,bname,bauthor,byear,btransf,bsbn, bcount,btranslattofarsi);";
Sql1 += "values({0},{1},{2},'{3}','{4}',{5},'{6}','{7}',{8} ,{9})" + "declare @pid as int=(select SCOPE_IDENTITY());";

string Sql2="insert into publish1(pid,pname) values(@pid,'{1}')";

Sql1 = string.Format(Sql1, this.BookId, this.GroupId, this.PublishId,
this.Bname, this.Bauthor, this.Byear, this.Translator,
this.Bsbn, this.Count, Convert.ToInt32(this.Transfarsi));

Sql2 = string.Format(Sql1,this.PublishId,this.pname);


da.connect();
da.insert1(Sql1,Sql2);

da.disconnect();




فرم دریافت اطلاعات
138236



با کمک کد شما کد transaction خودم رو اینجوری نوشتم ولی با خطای زیر مواجه میشم.
138237

Mahmoud.Afrad
چهارشنبه 16 دی 1394, 18:10 عصر
توی متد Add خط 3 آخرین کاراکتر رشته ; نباید باشه.
چون pid توسط کاربر وارد میشه و اتوماتیک مقدار نمیگیره نیازی به "declare @pid as int=(select SCOPE_IDENTITY());" نیست و همچنین @pid که به جاش مقدار this.PublishId رو قرار بده.
چون اطلاعات ناشر یکی بیشتر نیست میتونی دو رشته کوئری رو به هم متصل کنید.
Rollback هم برای زمانی که خطایی رخ بده لازمه تا تغییرات ناقص رو به حالت اولیه برگردونه.

Mahmoud Zaad
چهارشنبه 16 دی 1394, 18:18 عصر
سلام
شما یه اسکرین شات از دیتابیست بزار، به نظر تحلیل شما مشکل داره. اگه کار انتشاراتی باشه برای این کار به یک جدول کتاب فقط برای ثبت مشخصات کتاب به جز نام نویسنده، نام مترجم، نام ناشر
یک جدول ناشر
یک جدول نویسندگان
یک جدول مترجمان (البته شاید بشود سه جدول اخیر رو ادغام کرد و با یک فیلد از هم جدا کرد)
و در نهایت یک جدول واسط برای ارتباط اینها که در این جدول کد کتاب، کد ناشر، کد نویسنده، کد مترجم، سال چاپ و ... قرار میگیره.
حالا در نرم افزار، کاربر ابتدا باید مشخصات کتاب، ناشر، نویسنده و مترجمان رو وارد کرده باشه و در فرم نهایی فقط این موارد انتخاب بشه. و در این جدول آخری ثبت بشن.

baranbahari1320
چهارشنبه 16 دی 1394, 18:48 عصر
ممنون از توجه تون.پروژه کتابخانه هستش . ارتباط بین دو جدول کتاب و نویسنده رو براتون میذارم.
138238

Mahmoud Zaad
چهارشنبه 16 دی 1394, 20:04 عصر
خب همونطور که عرض کردم این طراحی مشکل داره، چون یک کتاب ممکنه چند ناشر داشته باشه، همین طور چند نویسنده و چند مترجم. حتی ممکنه کتاب یک بار در قطع وزیری چاپ بشه یک بار در قطع رقعی و ...
بنابراین شما به جداول،
مشخصات کتاب (نام کتاب، توضیحات و ... هیچ کدوم از موارد بالا اینجا قرار نمیگیره مگر اینکه بخواید آخرین وضعیت موارد بالا رو در این جدول نگه دارید برای افزایش سرعت کوئری ها)
جدول ناشران
جدول نویسندگان
جدول مترجمان
جدول ارتباطی شامل کدهای جداول کتاب، ناشران، نویسندگان و مترجمان بعلاوه سال چاپ، نوبت چاپ، شابک (اگر برای هر چاپ تغییر بکنه؟) و...
(البته میشه این جدول آخری نباشه و در همون جدول کتاب این کدها ثبت بشن منتها اگر ناشر و مترجم و ... تغییر کنن هر بار شما باید نام کتاب رو ثبت کنید به نظرم اصولی نیست.
مثلا
کتاب خوب-ناشر 1-مترجم 11
کتاب خوب-ناشر 1-مترجم 11
کتاب خوب-ناشر1-مترجم 22
که زیاد جالب نیست
)

الان نیازی به درج همزمان نیست، چون قبل از ثبت نهایی کاربر باید نام ناشر و نویسنده و ... رو ثبت کرده باشه. حالا اینکه چطور شما کاربری رو ساده کنید به خود شما بستگی داره مثلاً میشه یک دکمه جلوی تکست باکس کد ناشر گذاشت که با زدن اون کاربر لیست ناشرین رو ببینه و اگر ناشر مورد نظر وجود نداشت ثبتش کنه.
در کل ثبت همزمان برای مواردی هست که جداول به صورت Master - Details طراحی بشن ولی اینجا لزوماً اینطور نیست.

baranbahari1320
شنبه 19 دی 1394, 15:01 عصر
حرفتون کاملا منطقیه.ممنون از راهنماییتون.این تغییرات رو در پروژه ام لحاظ میکنم.