PDA

View Full Version : سوال: وارد کردن اطلاعات در دو یا چند جدول از database



daniyaltjm
یک شنبه 31 مرداد 1395, 13:40 عصر
سلام، چطوری میشه مقادیر چند تکست باکس رو در یک دستور insert به دو یا چند جدول داد؟ مثلا دو تا تکست باکس برای نام و نام خانوادگی و یک تکست باکس برای شماره تلفن و... که با زدن یک دکمه اطلاعات باید توی دو تا جدول ذخیره بشن.

mr.sirwan
یک شنبه 31 مرداد 1395, 13:44 عصر
میتونی داخل SP از دوتا دستور Insert پشت سر هم استفاده کنی

daniyaltjm
یک شنبه 31 مرداد 1395, 14:03 عصر
میتونی داخل SP از دوتا دستور Insert پشت سر هم استفاده کنی

منظورتون ازSP استورد پروسیجر هست؟ من از دستورات SqlCommand استفاده میکنم.
این کارو هم کردم توی SqlCommand ولی خطا میده!! میشه یه نمونه بنویسین ؟
به این صورت نوشتم خطا میده:
SqlCommand cm = new SqlCommand("insert into Tbl_Name(Name,Family,Addressl) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "') insert into Tbl_dress (Tel) values('"+textBox3.Text+"')" , con);

mr.sirwan
یک شنبه 31 مرداد 1395, 14:59 عصر
منظور Store Procedure هستش، همین کدارو داخل یه استور پروسیجر بنویسین و یه اسم واسش قرار بدین و داخل SQLCommand فراخوانی کنین

daniyaltjm
یک شنبه 31 مرداد 1395, 17:47 عصر
منظور Store Procedure هستش، همین کدارو داخل یه استور پروسیجر بنویسین و یه اسم واسش قرار بدین و داخل SQLCommand فراخوانی کنین

من نمی خوام از استورد پروسیجر استفاده کنم فقط از طریق سی شارپ می خوام این کارو انجام بدم!

من این کد رو نوشتم ولی چند تا رکورد ذخیره میشه .

if (textBox1.Text != "" & textBox2.Text != "")
{


SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=TelAddress;Integrated Security=True");
SqlCommand cm = new SqlCommand();
cm.Connection = con;
cm.CommandText = "insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')";
con.Open();
cm.ExecuteNonQuery();
con.Close();
cm.CommandText = "insert into Tbl_Address(Tel) values('" + textBox3.Text + "')";
con.Open();
cm.ExecuteNonQuery();
con.Close();
MessageBox.Show("مخاطب با موفقیت ذخیره شد", "ذخیره", MessageBoxButtons.OK, MessageBoxIcon.Information);


}
else
{
MessageBox.Show("!اطلاعات را کامل وارد نکردید", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

juza66
یک شنبه 31 مرداد 1395, 18:17 عصر
سلام

این رو بصورت تابع بنویس و فقط sqlcommand رو دوبار بنویس

juza66
یک شنبه 31 مرداد 1395, 18:19 عصر
اینجوری این رو تابع کن



Private void Inserttbl(string strcommand)
{

SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=TelAddress;Integrated Security=True");
SqlCommand cm = new SqlCommand(strcommand);
cm.Connection = con;
con.Open();
cm.ExecuteNonQuery();
con.Close();

{






اینجوری ثبت کن




Inserttbl("insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')")




دوبار تابع رو صدا بزن و مقدار command بده


موفق و پیروز

daniyaltjm
یک شنبه 31 مرداد 1395, 18:36 عصر
اینجوری این رو تابع کن



Private void Inserttbl(string strcommand)
{

SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=TelAddress;Integrated Security=True");
SqlCommand cm = new SqlCommand(strcommand);
cm.Connection = con;
cm.CommandText = "insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')";
con.Open();
cm.ExecuteNonQuery();
con.Close();

{






اینجوری ثبت کن




Inserttbl("insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')")





دوبار تابع رو صدا بزن و مقدار command بده


موفق و پیروز

چرا به تابع تبدیل کنم؟ کدای من کار میکنه ولی مشکل اینه که وقتی یک رکورد جدید ثبت میکنم رکورد های قدیمی هم دوباره ثبت میشن!
اگه اینطوری ثبت کنم پس فیلد Tel کجا رفته؟

juza66
یک شنبه 31 مرداد 1395, 18:44 عصر
تابع رو دوبار صدا بزن

موقعی که داشتم پست رو ویرایش میکردم شما جواب دادی الان پست قبلی من رو نگاه کنید

sqlcommand رو دوبار در تابعت صدا بزن عزیز

daniyaltjm
یک شنبه 31 مرداد 1395, 18:57 عصر
تابع رو دوبار صدا بزن

موقعی که داشتم پست رو ویرایش میکردم شما جواب دادی الان پست قبلی من رو نگاه کنید

sqlcommand رو دوبار در تابعت صدا بزن عزیز

مشکل اینه که شما توی تابع فقط اطلاعات نام،نام خانوادگی،آدرس رو ذخیره کردید و فیلد تلفن (Tel) رو من در کدتون نمی بینم!
بعد منظورتون از دوبار صدا زدن چیه؟ اینطوری که دو تا رکورد ثبت میشه ولی من می خوام یک رکورد توی یک جدول با فیلد های نام،نامخانوادگی،آدرس و یک رکورد که تلفن رو ذخیره میکنه توی جدول دیگه ثبت بشه.

juza66
یک شنبه 31 مرداد 1395, 19:01 عصر
دوست عزیز


شما مگه نه این کد رو میزی جدول اولت پر میشه؟



Inserttbl("insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')")



دوباره تابع رو صدا میزنی ایندفعه تلفن رو ذخیره میکنه


Inserttbl("insert into Tbl_Address(Tel) values('" + textBox3.Text + "')")

daniyaltjm
یک شنبه 31 مرداد 1395, 19:05 عصر
دوست عزیز


شما مگه نه این کد رو میزی جدول اولت پر میشه؟



Inserttbl("insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')")



دوباره تابع رو صدا میزنی ایندفعه تلفن رو ذخیره میکنه


Inserttbl("insert into Tbl_Address(Tel) values('" + textBox3.Text + "')")


ممنون حالا در صورتی که نخوام از تابع استفاده کنم آیا مشکلش کجاست؟ و چرا در کدهای خودم رکورد های قبلی هم ثبت می شدن؟

mrprestige
یک شنبه 31 مرداد 1395, 20:21 عصر
سلام وقت بخیر ، دوست عزیز شما برای اینکه بطور همزمان اطلاعاتتون رو داخل دو جدول یا بیشتر ثبت کنید بهتره از Datacommand های پارامتر دار استفاده کنید ( اگر نمیخواید طبق فرمایشات دوستمون juza66 (http://barnamenevis.org/member.php?177324-juza66) از تابع استفاده کنید ) یه مثال برات میزنم

sqlcmd.CommandText = "INSERT INTO Table1(Name, Tel) VALUES(@Name, @Tel)";
sqlcmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = Name;
sqlcmd.Parameters.Add("@Tel", SqlDbType.int).Value = Tel;
sqlCmd.ExecuteNonQuery();
sqlCmd.Parameters.Clear();
sqlcmd.CommandText = "INSERT INTO Table2(Adres, Tel2) VALUES(@Adres, @Tel2)";
sqlcmd.Parameters.Add("@Adres", SqlDbType.VarChar).Value = Adres;
sqlcmd.Parameters.Add("@Tel2", SqlDbType.int).Value = @Tel2;
sqlCmd.ExecuteNonQuery();

موفق باشید

daniyaltjm
دوشنبه 01 شهریور 1395, 01:02 صبح
سلام وقت بخیر ، دوست عزیز شما برای اینکه بطور همزمان اطلاعاتتون رو داخل دو جدول یا بیشتر ثبت کنید بهتره از Datacommand های پارامتر دار استفاده کنید ( اگر نمیخواید طبق فرمایشات دوستمون juza66 (http://barnamenevis.org/member.php?177324-juza66) از تابع استفاده کنید ) یه مثال برات میزنم

sqlcmd.CommandText = "INSERT INTO Table1(Name, Tel) VALUES(@Name, @Tel)";
sqlcmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = Name;
sqlcmd.Parameters.Add("@Tel", SqlDbType.int).Value = Tel;
sqlCmd.ExecuteNonQuery();
sqlCmd.Parameters.Clear();
sqlcmd.CommandText = "INSERT INTO Table2(Adres, Tel2) VALUES(@Adres, @Tel2)";
sqlcmd.Parameters.Add("@Adres", SqlDbType.VarChar).Value = Adres;
sqlcmd.Parameters.Add("@Tel2", SqlDbType.int).Value = @Tel2;
sqlCmd.ExecuteNonQuery();

موفق باشید

ممنون همه روشها جواب دادن و تازه متوجه شدم که اشکال از درج نیست چون وقتی با هر دو روش شما و آقای juza66 انجام دادم و رکورد درست توی بانک ذخیره شد، الان متوجه شدم که وقتی می خوام اطلاعات رو نمایش بدم از هر رکورد دو تا یا بیشتر نشون میده نمیدونم چرا!!!

juza66
دوشنبه 01 شهریور 1395, 01:11 صبح
سلام مجدد

کد لود کردن دیتاگریدت رو بذار
اطلاعات دیتا بیس رو هم حذف کن
کد دکمه ثبت هم بذار

تا من و دوستان ببینیم چکار میکنید ..

daniyaltjm
دوشنبه 01 شهریور 1395, 14:58 عصر
سلام مجدد

کد لود کردن دیتاگریدت رو بذار
اطلاعات دیتا بیس رو هم حذف کن
کد دکمه ثبت هم بذار

تا من و دوستان ببینیم چکار میکنید ..

باشه

این کد لود کردن دیتاگرید:


private void radButton4_Click_1(object sender, EventArgs e)
{
Upd("select ID_Name,Name,Family,Tel,Address from Tbl_Name,Tbl_Address");


}

که از این تابع upd استفاده میکنه:

public void Upd(string strcommand)
{


SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=TelAddress;Integrated Security=True");
SqlCommand cm = new SqlCommand();
cm.Connection=con;
cm.CommandText = strcommand;
cm.Connection.Open();
SqlDataAdapter da = new SqlDataAdapter(cm);
DataTable dt = new DataTable();
da.Fill(dt);
radGridView1.DataSource = dt;
cm.Connection.Close();

}



کد دکمه ثبت:


if (textBox1.Text != "" & textBox2.Text != "" & textBox3.Text !="")
{
Inserttbl("insert into Tbl_Name(Name,Family,Address) values('" + textBox1.Text + "','" + textBox2.Text + "','" + textBox4.Text + "')");
Inserttbl(" insert into Tbl_Address(Tel) values('" + textBox3.Text + "')");
MessageBox.Show("مخاطب با موفقیت ذخیره شد", "ذخیره", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
MessageBox.Show("!اطلاعات را کامل وارد نکردید", "خطا", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


که از این تابع استفاده میکنه:



public void Inserttbl(string strcommand)
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=TelAddress;Integrated Security=True");
SqlCommand cm = new SqlCommand(strcommand);
cm.Connection = con;
con.Open();
cm.ExecuteNonQuery();
con.Close();
}



من وقتی در کد لود از هدر استفاده میکنم بهم خطا میده که از رنج محدوده خارج شدم ولی این طور نیست و من به اندازه ستون هام استفاده کردم ببینید:


public void Upd(string strcommand)
{
SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=TelAddress;Integrated Security=True");
SqlCommand cm = new SqlCommand();
cm.Connection=con;
cm.CommandText = strcommand;
cm.Connection.Open();
SqlDataAdapter da = new SqlDataAdapter(cm);
DataTable dt = new DataTable();
da.Fill(dt);
radGridView1.DataSource = dt;
radGridView1.Columns[0].HeaderText = "کد";
radGridView1.Columns[1].HeaderText = "نام";
radGridView1.Columns[2].HeaderText = "نام خانوادگی";
radGridView1.Columns[3].HeaderText = "تلفن";
radGridView1.Columns[4].HeaderText = "آدرس";
radGridView1.Columns[0].Width = 50;
radGridView1.Columns[1].Width = 100;
radGridView1.Columns[2].Width = 100;
radGridView1.Columns[3].Width = 120;
radGridView1.Columns[4].Width = 400;
cm.Connection.Close();

}

mr.sirwan
دوشنبه 01 شهریور 1395, 16:57 عصر
دوست عزیز، رکوردهای فراخوانی شده حاصل از دستور Select ی که نوشتین ضرب دکارتزی میشن، یعنی به فرض در جدول tbl_name به تعداد 10 رکورد موجود باشه و همچنین در جدول tbl_Address تعداد 5 سطر موجود باشه این مقادیر با هم ضرب دکارتزی میشن و کوئری Select شما به تعداد 50 سطر رکورد واستون برمگیردونه، برای مرتفع کردن این مشکل باید شرط برقراری کلید خارجی موجود در tbl_Address و کلید اصلی موحود در tbl_name رو قرار بدین، بدین صورت:

Select * From tbl_name, tblAddress
Where tbl_Address.FK_ID_Name = tbl_Name.ID_Name

منظور از FK همون کلید خارجی وابسته به جدول tbl_name هستش

سوالی داشتین بفرمایین

rahmatipoor
دوشنبه 01 شهریور 1395, 17:43 عصر
سلام دوست خوب


سلام، چطوری میشه مقادیر چند تکست باکس رو در یک دستور insert به دو یا چند جدول داد؟


در مورد سوال اول بین دو تا دستور علامت سمی کالن ( ; ) بذار
هرچند تا دستور هم میتونی با یک کامند اجرا کنی :
اینجوری :


Insert into tbl1 (field1,field2,...) values (value1,value2,...)
;
Insert into tbl2 (field1,field2,...) values (value1,value2,...)
;
Insert into tbl3 (field1,field2,...) values (value1,value2,...)
;
.
.
.





الان متوجه شدم که وقتی می خوام اطلاعات رو نمایش بدم از هر رکورد دو تا یا بیشتر نشون میده نمیدونم چرا!!!

راه حلش اینه که دو تا تابع داشته باشی یکی برای اجرای دستورات SELECT و یکی برای اجرای سایر دستورات:
مثل این کاری که من انجام میدم. البته من سه لایه برنامه نوشتم و توی یک لایه ( BAL ) کامند رو میسازم و ارسال میکنم به لایه DAL که این متدها توی اون هست و وظیفه اش ارتباط با دیتابیس هست:

public void ExexuteSelectCommand(SqlCommand cmd)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
dv = new DataView();
cmd.Connection = MyCn;
if (MyCn.State == ConnectionState.Closed)
{
MyCn.Open();
}
cmd.ExecuteNonQuery();
da.Fill(dt);
dv = dt.DefaultView;
MyCn.Close();
MyCn.Dispose();




}

//************************************************** ********************

public void ExexuteCommand(SqlCommand cmd)
{

cmd.Connection = MyCn;
if (MyCn.State == ConnectionState.Closed)
{
MyCn.Open();
}
cmd.ExecuteNonQuery();
MyCn.Close();
MyCn.Dispose();

}

نکته اش هم اینه که موقع اجرای دستورات از نوع Select نیاز به اجرای متد Fill دیتا اداپتر هست و در غیر این صورت نباید این متد رو اجرا کنید یعنی نباید این دوتا خط رو اجرا کنید :

da.Fill(dt);
dv = dt.DefaultView;


کل کد لایه DAL بعنی ارتباط با دیتابیس هم اینه :


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;

namespace Daftar_Rahnama
{
class clsAccessData
{
string ConStr = @"Data Source=.\SQLABRAR ; AttachDbFilename=" + Application.StartupPath
+ @"\Data\Daftar_Rahnama.mdf; Initial Catalog=Daftar_Rahnama; Integrated Security=True";


public DataView dv;
SqlConnection MyCn;

public clsAccessData()
{
MyCn = new SqlConnection(ConStr);
}

public void ExexuteSelectCommand(SqlCommand cmd)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
dv = new DataView();
cmd.Connection = MyCn;
if (MyCn.State == ConnectionState.Closed)
{
MyCn.Open();
}
cmd.ExecuteNonQuery();
da.Fill(dt);
dv = dt.DefaultView;
MyCn.Close();
MyCn.Dispose();




}

//************************************************** ********************

public void ExexuteCommand(SqlCommand cmd)
{

cmd.Connection = MyCn;
if (MyCn.State == ConnectionState.Closed)
{
MyCn.Open();
}
cmd.ExecuteNonQuery();
MyCn.Close();
MyCn.Dispose();

}




}
}

daniyaltjm
دوشنبه 01 شهریور 1395, 17:56 عصر
دوست عزیز، رکوردهای فراخوانی شده حاصل از دستور Select ی که نوشتین ضرب دکارتزی میشن، یعنی به فرض در جدول tbl_name به تعداد 10 رکورد موجود باشه و همچنین در جدول tbl_Address تعداد 5 سطر موجود باشه این مقادیر با هم ضرب دکارتزی میشن و کوئری Select شما به تعداد 50 سطر رکورد واستون برمگیردونه، برای مرتفع کردن این مشکل باید شرط برقراری کلید خارجی موجود در tbl_Address و کلید اصلی موحود در tbl_name رو قرار بدین، بدین صورت:

Select * From tbl_name, tblAddress
Where tbl_Address.FK_ID_Name = tbl_Name.ID_Name

منظور از FK همون کلید خارجی وابسته به جدول tbl_name هستش

سوالی داشتین بفرمایین

ممنون مشکل اینه که من چطوری به کلید خارجیم مقدار کلید اصلی اون جدول دیگم رو بدم؟ ارتباط بین کلید اصلی و خارجی هم بر قرار کردم ولی نمی دونم چطور مقدار کلید اصلی رو کپی کنم برای کلید خارجی.

rahmatipoor
دوشنبه 01 شهریور 1395, 18:02 عصر
این هم نمونه کد دستور select توی لایه BAL که چطوری کامند بسازی و به لایه DAL برای اجرا پاس بدی.
با این روش جلوی SQL Injection هم گرفته میشه و نرم افزارت از این طریق هک نمیشه:


public DataView SelectOneGroup(int GroupID)
{
SqlCommand myCmd = new SqlCommand();
myCmd.CommandText = @"
SELECT GroupID, GroupName, Tozihat
FROM tblGroups
WHERE (GroupID = @GroupID)";

//
myCmd.Parameters.AddWithValue("@GroupID", GroupID);

//
clsAccessData dbAccess = new clsAccessData();
dbAccess.ExexuteSelectCommand(myCmd);
return dbAccess.dv;
}


این هم یک نمونه دیگه که دستوری غیر از Select رو اجرا کرده و همچنین چند تا دستور اس کیو ال از طریق یک کامند ارسال میشه



public void DeleteGroup(int GroupID)
{
SqlCommand myCmd = new SqlCommand();
myCmd.CommandText = @"
--حذف فايلهاي اعضا
DELETE FROM tblFile
WHERE (OzvID IN
(SELECT ID
FROM tblDaftarRahnam
WHERE (Parent_GroupID = @GroupID)));


--حذف اعضا
DELETE FROM tblDaftarRahnam
WHERE (Parent_GroupID = @GroupID);

--حذف گروه
DELETE FROM tblGroups
WHERE (GroupID = @GroupID)";

//
myCmd.Parameters.AddWithValue("@GroupID", GroupID);

//
clsAccessData dbAccess = new clsAccessData();
dbAccess.ExexuteCommand(myCmd);
}

mr.sirwan
دوشنبه 01 شهریور 1395, 18:20 عصر
ممنون مشکل اینه که من چطوری به کلید خارجیم مقدار کلید اصلی اون جدول دیگم رو بدم؟ ارتباط بین کلید اصلی و خارجی هم بر قرار کردم ولی نمی دونم چطور مقدار کلید اصلی رو کپی کنم برای کلید خارجی.

شما میتونی واسه کوئری insert داخل جدول اصلیت یه کد کوچیک اضافه کنی و به راحتی مقدار فیلد AutoIncreament رو برگردونی، به اینصورت:

Inserttbl("insert into Tbl_Name(Name,Family,Address)
Output Iserted.ID values()

کدی که بولد کردم ایدی اخرین سطری که در جدول tbl_name درج شده رو برمیگردونه حالا شما برای اجرای کوئری insert داخل جدول tbl_name به جای Command.ExecuteNoneQuery از این دستور استفاده کنی:

int InsertedId = (int) Command.ExecuteScalar


و درنهایت برای دستور insert به جدول tbl_address مقادیر Tel و InsertedId مثل روش خودت اضافه کنی

daniyaltjm
دوشنبه 01 شهریور 1395, 18:22 عصر
این هم نمونه کد دستور select توی لایه BAL که چطوری کامند بسازی و به لایه DAL برای اجرا پاس بدی.
با این روش جلوی SQL Injection هم گرفته میشه و نرم افزارت از این طریق هک نمیشه:


public DataView SelectOneGroup(int GroupID)
{
SqlCommand myCmd = new SqlCommand();
myCmd.CommandText = @"
SELECT GroupID, GroupName, Tozihat
FROM tblGroups
WHERE (GroupID = @GroupID)";

//
myCmd.Parameters.AddWithValue("@GroupID", GroupID);

//
clsAccessData dbAccess = new clsAccessData();
dbAccess.ExexuteSelectCommand(myCmd);
return dbAccess.dv;
}


این هم یک نمونه دیگه که دستوری غیر از Select رو اجرا کرده و همچنین چند تا دستور اس کیو ال از طریق یک کامند ارسال میشه



public void DeleteGroup(int GroupID)
{
SqlCommand myCmd = new SqlCommand();
myCmd.CommandText = @"
--حذف فايلهاي اعضا
DELETE FROM tblFile
WHERE (OzvID IN
(SELECT ID
FROM tblDaftarRahnam
WHERE (Parent_GroupID = @GroupID)));


--حذف اعضا
DELETE FROM tblDaftarRahnam
WHERE (Parent_GroupID = @GroupID);

--حذف گروه
DELETE FROM tblGroups
WHERE (GroupID = @GroupID)";

//
myCmd.Parameters.AddWithValue("@GroupID", GroupID);

//
clsAccessData dbAccess = new clsAccessData();
dbAccess.ExexuteCommand(myCmd);
}


ممنون که وقت گذاشتی دوست عزیز، ولی یک تیکه از کداتو نفهمیدم .

rahmatipoor
دوشنبه 01 شهریور 1395, 18:23 عصر
همچنین بگم که اون موضوعی که گفتی دو بار اطلاعات رو برمیگردونه من اوایل برنامه نویسی همین مشکل رو داشتم و اون موقع کلی سر و کله زدم تا مشکلش رو فهمیدم.

rahmatipoor
دوشنبه 01 شهریور 1395, 18:24 عصر
بگو در خدمتم

mr.sirwan
دوشنبه 01 شهریور 1395, 18:25 عصر
همچنین بگم که اون موضوعی که گفتی دو بار اطلاعات رو برمیگردونه من اوایل برنامه نویسی همین مشکل رو داشتم و اون موقع کلی سر و کله زدم تا مشکلش رو فهمیدم.

دوست عزیز به نظرم همون مشکل ضرب دکارتزی هستش که شمام باهاش سروکله زدی

rahmatipoor
دوشنبه 01 شهریور 1395, 18:32 عصر
دوست عزیز به نظرم همون مشکل ضرب دکارتزی هستش که شمام باهاش سروکله زدی

ضرب کارتزین که شما میگی باید تعداد رکوردها هر بار فرق کنه
ولی این مشکل که من داشتم و این دوستمون دارن هر سری اطلاعات رو دو بار ثبت میکنه که در صورتی که از این روش استفاده کنند هیچ مشکلی پیش نمیاد.

البته عرض کنم این مشکل مربوط به بیشتر از 2 سال قبل بنده بوده و الآن دیگه یه مقدار سطح کارمون بالاتر اومده مثلا

mr.sirwan
دوشنبه 01 شهریور 1395, 18:36 عصر
ضرب کارتزین که شما میگی باید تعداد رکوردها هر بار فرق کنه
ولی این مشکل که من داشتم و این دوستمون دارن هر سری اطلاعات رو دو بار ثبت میکنه که در صورتی که از این روش استفاده کنند هیچ مشکلی پیش نمیاد.

البته عرض کنم این مشکل مربوط به بیشتر از 2 سال قبل بنده بوده و الآن دیگه یه مقدار سطح کارمون بالاتر اومده مثلا

نقل قول از ایشون: "ممنون همه روشها جواب دادن و تازه متوجه شدم که اشکال از درج نیست چون وقتی با هر دو روش شما و آقای juza66 (http://juza66) انجام دادم و رکورد درست توی بانک ذخیره شد، الان متوجه شدم که وقتی می خوام اطلاعات رو نمایش بدم از هر رکورد دو تا یا بیشتر نشون میده نمیدونم چرا!!!"

juza66
دوشنبه 01 شهریور 1395, 18:42 عصر
سلام

اول اینکه سلکتت دوتا نام رو صدا زده،
دوم چرا دیتاگرید رو در زمان لود ایجاد میکنی؟
ثبتت درسته،
لود هم درسته،

یک عکس از نمایش اطلاعات دیتاگریدت،
یک عکس از دیتا در اس کیوالت بذار ببینم چرا چندبار لود میشه


منتظرم

rahmatipoor
دوشنبه 01 شهریور 1395, 18:47 عصر
توضیحات کلی برنامه نویسی چندلایه ( 3 لایه ) :

شما یک لایه ( کلاس ) طراحی میکنی

لایه DAL یا ارتباط با داده ها :
یک کلاس ایجاد میکنی و اسمش رو هرچی دوست داشتی میذاری. من اسمش رو clsAccessData گذاشتم.
توی این لایه کلاسهای کار با دیتابیس و کانکشن استرینگ و ... رو تعریف می کنی . همونی که توی پست اولم برات گذاشتم. این کلاس دو تا متد داره که هر دو از نوع Public هستند چون باید توی لایه های دیگه فراخوانی بشن.
یکی برای اجرای دستوراتی که Select هستند و یکی برای سایر دستورات غیر . Select
اینطوری :


using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;

namespace Daftar_Rahnama
{
class clsAccessData
{
string ConStr = @"Data Source=.\SQLABRAR ; AttachDbFilename=" + Application.StartupPath
+ @"\Data\Daftar_Rahnama.mdf; Initial Catalog=Daftar_Rahnama; Integrated Security=True";


public DataView dv;
SqlConnection MyCn;

public clsAccessData()
{
MyCn = new SqlConnection(ConStr);
}

public void ExexuteSelectCommand(SqlCommand cmd)
{
DataTable dt = new DataTable();
SqlDataAdapter da = new SqlDataAdapter(cmd);
dv = new DataView();
cmd.Connection = MyCn;
if (MyCn.State == ConnectionState.Closed)
{
MyCn.Open();
}
cmd.ExecuteNonQuery();
da.Fill(dt);
dv = dt.DefaultView;
MyCn.Close();
MyCn.Dispose();




}

//************************************************** ********************

public void ExexuteCommand(SqlCommand cmd)
{

cmd.Connection = MyCn;
if (MyCn.State == ConnectionState.Closed)
{
MyCn.Open();
}
cmd.ExecuteNonQuery();
MyCn.Close();
MyCn.Dispose();

}




}
}



خوبیش هم اینه که فقط یک بار نیازه کانکشن استرینگ و دستورات اتصال به بانک رو بنویسی و هر وقت خواستی تغییر بدی فقط همین یک جا تغییر میدی و اگه مطمئن باشی درست هستند دیگه خیالت راحته که عیب کار جای دیگه است و خیلی راحت میتونی دیباگ کنی

حالا برای کارهای مشابه مثلا برای دفتر تلفن یک کلاس دیگه تعریف میکنی مثلا (clsTel) و مثل پست دوم توابع موردنیاز و کامندها رو به شکلی که قبلا توضیح دادم اونجا می نویسی و و برای اجرا یک نمونه از کلاس DAL ایجاد میکنی و کامندها رو به اون پاس میدی تا اجرا کنه( به این لایه میگن BAL یا لایه منطق )
توی این لایه برای قسمتهای مختلف میتونی کلاسهای مختلف داشته باشی مثلا یک کلاس برای بک آپ و ریستور ، یک کلاس برای کار با دفتر تلفن و .... .
متدهایی هم که باید از لایه های دیگه فراخوانی بشن باید Public تعریف کنی
اینطوری :


دستورات Select :

public DataView SelectOneGroup(int GroupID)
{
SqlCommand myCmd = new SqlCommand();
myCmd.CommandText = @"
SELECT GroupID, GroupName, Tozihat
FROM tblGroups
WHERE (GroupID = @GroupID)";

//
myCmd.Parameters.AddWithValue("@GroupID", GroupID);

//
clsAccessData dbAccess = new clsAccessData();
dbAccess.ExexuteSelectCommand(myCmd);
return dbAccess.dv;
}


دستورات غیر از Select :



public void DeleteGroup(int GroupID)
{
SqlCommand myCmd = new SqlCommand();
myCmd.CommandText = @"
--حذف فايلهاي اعضا
DELETE FROM tblFile
WHERE (OzvID IN
(SELECT ID
FROM tblDaftarRahnam
WHERE (Parent_GroupID = @GroupID)));


--حذف اعضا
DELETE FROM tblDaftarRahnam
WHERE (Parent_GroupID = @GroupID);

--حذف گروه
DELETE FROM tblGroups
WHERE (GroupID = @GroupID)";

//
myCmd.Parameters.AddWithValue("@GroupID", GroupID);

//
clsAccessData dbAccess = new clsAccessData();
dbAccess.ExexuteCommand(myCmd);
}



توی فرمهات هم از کلاس CLsTel نمونه میسازی و متد موردنظرت رو اجرا میکنی. به عنوان مثال:


ClsTel MyTel = new ClsTel

Mytel.DeleteGroup(5);


به این میگن برنامه نویسی چند لایه.

مثلا شما خواستی برنامه ات رو تحت وب کنی دیگه نیاز نیست همه لایه ها رو از نو بنویسی . فقط کافیه فرمهای تحت وب رو طراحی کنی و از متدهایی که قبلا نوشتی استفاده کنی
عیب یابی هم خیلی راحته. کدهات هم تمیز هستند

daniyaltjm
دوشنبه 01 شهریور 1395, 21:02 عصر
<b>Output Iserted.ID</b> values()

این کدی که نوشتین دقیقا چکار میکنه درست هم نوشته نشده اینطوری باید باشه؟

Output Inserted.ID values()


در کل مشکل همینه که فیلد کلید اصلی جدول Tbl_Name باید در کلید خارجی جدول Tbl_Address موقع درج یک رکورد کپی بشه.

mr.sirwan
دوشنبه 01 شهریور 1395, 21:22 عصر
<b>Output Iserted.ID</b> values()

این کدی که نوشتین دقیقا چکار میکنه درست هم نوشته نشده اینطوری باید باشه؟

Output Inserted.ID values()


در کل مشکل همینه که فیلد کلید اصلی جدول Tbl_Name باید در کلید خارجی جدول Tbl_Address موقع درج یک رکورد کپی بشه.

دوست عزیز همونطور که گفتم ایدی اخرین سطری که در جدول tbl_name درج شده (سطری که هم اکنون در حال درجش هستین) رو برمیگردونه و اون تگ ها <b> که میبینین مشکل از ادیتور سایتمون هستش این تگ رو واسه بولد کردن این دستور گذاشتم، لطفا پستی که گذاشتم رو به دقت مطالعه کنین چون توضیح دادم که مستلزم انجام چه کار هایی هستین

اجازه بدین کدتون رو واستون بازنویسی کنم:

دستورات زیر که دوست خوبمون mrprestige (http://barnamenevis.org/member.php?338119-mrprestige) گذاشتن رو ویرایش میکنم

sqlcmd.CommandText = "insert into Tbl_Name(Name,Family,Address) OUTPUT INSERTED.ID_Name VALUES(@NAME, @FAMILY, @ADDRESS)";

sqlcmd.Parameters.Add("@NAME", SqlDbType.VarChar).Value = NAME;

sqlcmd.Parameters.Add("@FAMILY", SqlDbType.VARCHAR).Value = FAMILY;

sqlcmd.Parameters.Add("@ADDRESS", SqlDbType.VARCHAR).Value = ADDRESS;

int InsertedId = (int) sqlCmd.ExecuteScalar();

sqlCmd.Parameters.Clear();

sqlcmd.CommandText = "INSERT INTO Tbl_Address(Name_Id, Tel) VALUES(@InsertedId, @Tel)";

sqlcmd.Parameters.Add("@InsertedId", SqlDbType.int).Value = InsertedId;

sqlcmd.Parameters.Add("@Tel", SqlDbType.varchar).Value = @Tel;

sqlCmd.ExecuteNonQuery();

daniyaltjm
دوشنبه 01 شهریور 1395, 21:25 عصر
سلام

اول اینکه سلکتت دوتا نام رو صدا زده،
دوم چرا دیتاگرید رو در زمان لود ایجاد میکنی؟
ثبتت درسته،
لود هم درسته،

یک عکس از نمایش اطلاعات دیتاگریدت،
یک عکس از دیتا در اس کیوالت بذار ببینم چرا چندبار لود میشه


منتظرم



اول اینکه سلکتت دوتا نام رو صدا زده،

نه اون ID_Name هست !!


دوم چرا دیتاگرید رو در زمان لود ایجاد میکنی؟

خوب چه اشکالی داره؟ و منظورتون اینه که بایندش کنم؟


یک عکس از نمایش اطلاعات دیتاگریدت،

142116


یک عکس از دیتا در اس کیوالت بذار ببینم چرا چندبار لود میشه

جدول Tbl_Name

142117


جدول Tbl_Address

142118

juza66
سه شنبه 02 شهریور 1395, 00:01 صبح
به کوئری دریافتت نگاه نکردم، join نکردی دو تیبل رو بخاط همین کوئریت دوبار اجرا میشه


SELECT column_name(s)
FROM table1
INNERJOIN table2
ONtable1.column_name=table2.column_name;


اینجوری بنویس