我需要先将值插入到几个表中,然后我必须从表学院中检索大学ID,然后将教师名称插入到表教员中并由SQL Server ID生成。完成所有这些后,我必须将两个ID插入另一个表中。
问题是我必须关闭读者,在我这样做之后,我无法从它们中检索这些ID,因此应该保存它们的变量为null。这是我的代码。怎么做正确?
抱歉,我是C#和SQL Server的新手。
// reading data into combobox
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from colege", myConnection);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
comboBox1.Items.Add(myReader["name"].ToString());
// Console.WriteLine(myReader["Column2"].ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
myConnection.Close();
private void button1_Click(object sender, EventArgs e)
{
string item = comboBox1.Text.ToString();
// MessageBox.Show(item);
SqlConnection myConnection = new SqlConnection("user id=bogdan_db;" +
"password=1234;server=localhost;" +
"Trusted_Connection=yes;" +
"database=cafedrascience; " +
"connection timeout=30");
try
{
myConnection.Open();
}
catch (Exception E)
{
Console.WriteLine(E.ToString());
}
// reading data into combobox
String colegeid = null;
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from colege where name like'" + item + "'", myConnection);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
colegeid = myReader["id"].ToString();
// Console.WriteLine(myReader["Column2"].ToString());
}
myReader.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
String facultyid = null;
try
{
SqlDataReader myReader1 = null;
SqlCommand myCommand = new SqlCommand("select * from depart where name like'" + textBox1.Text + "'",
myConnection);
myReader1 = myCommand.ExecuteReader();
while (myReader1.Read())
{
facultyid = myReader1["id"].ToString();
}
myReader1.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
SqlCommand myCommand1 = new SqlCommand("INSERT INTO coledge_faculty (coledge_id, faculty_id) " +
"Values ('"+colegeid+"''"+facultyid+"')", myConnection);
myCommand1.ExecuteNonQuery();
// MessageBox.Show(colegeid);
// MessageBox.Show(facultyid);
myConnection.Close();
}
答案 0 :(得分:3)
我可以强调你的代码最重要的一点是你应该使用parameterised queries,除了SQL注入的明显风险之外,它还可以保护你免受格式错误的SQL,通过转换截断数据,并且它允许你使用缓存的执行计划。
接下来要指出的是should not be using SELECT *
in production code,例如
SqlCommand myCommand = new SqlCommand("select * from colege where name like'" + item + "'",
myConnection);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
colegeid = myReader["id"].ToString();
// Console.WriteLine(myReader["Column2"].ToString());
}
为什么还要从数据库中检索colege
的所有列,如果您只关心列id
,则通过网络发送它们?
最后你对问题的诊断不正确:
问题是我必须关闭读者,在我这样做之后,我无法从这些读者那里撤回这些ID,因此应该保存它们的变量为null
如果为字符串变量colegeid
分配了一个从数据读取器中读取的值,则在关闭阅读器后它不会为空,它将保留您指定的值。变量为null的最可能原因是因为您的读者不返回任何行,因此您永远不会为其赋值。
现在,咆哮,我会实际回答你的问题。您大大超过了问题的复杂性,您不需要将值检索到应用程序层只是为了将它们插入到另一个表中,您可以在数据库中的单个查询中执行此操作:
INSERT INTO coledge_faculty (coledge_id, faculty_id)
SELECT c.id, d.id
FROM depart AS d
CROSS JOIN colege AS c
WHERE d.Name = @Depart
AND c.Name = @Colege;
然后它只是从c#:
调用此SQL的情况string item = comboBox1.Text.ToString();
string connectionString = "user id=bogdan_db; password=1234;server=localhost; Trusted_Connection=yes; database=cafedrascience; connection timeout=30";
string sql = @"INSERT INTO coledge_faculty (coledge_id, faculty_id)
SELECT c.id, d.id
FROM depart AS d
CROSS JOIN colege AS c
WHERE d.Name = @Depart
AND c.Name = @Colege;";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("@Colege", SqlDbType.VarChar, 50).Value = item;
command.Parameters.Add("@Depart", SqlDbType.VarChar, 50).Value = textBox1.Text;
connection.Open();
command.ExecuteNonQuery();
}
将using
块与实现IDisposable
的对象一起使用通常是一个好主意,这样可以确保在完成这些操作后释放资源(不要将此与之混淆)由于无法重用连接,.NET在后台有连接池,所以它会为你重用连接,你不应该保持你的SqlConnection对象可用,以防你需要再次使用它。)
在另一个不相关的说明中,我也认为你对try / catch块过于自由,或者至少没有正确处理异常,以此为例:
try
{
myConnection.Open();
}
catch (Exception E)
{
Console.WriteLine(E.ToString());
}
如果myConnection.Open()
确实抛出错误,您仍然继续使用该方法。你会继续,直到你到达这里:
SqlCommand myCommand = new SqlCommand("select * from colege where name like'" + item + "'",
myConnection);
myReader = myCommand.ExecuteReader();
你会得到另一个例外,这个命令需要一个开放且可用的Sql连接,所以你去了例外。
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
同样,您不会退出该方法,但继续操作,稍后当您尝试再次使用该连接时,您将收到相同的错误。该方法再次继续,您将第三次使用已关闭的连接尝试插入两个从未分配的变量,因为异常被抛入您的数据库。好的,使用try catch块,但是对异常执行一些有意义的操作并退出方法。
答案 1 :(得分:-1)
private void BtnAdd_Click(object sender, EventArgs e)
{
//con.Open();
cmd = new SqlCommand("INSERT INTO TBL_STORE VALUES (N'"+txt_store_name.Text.Trim()+"',N'"+txt_store_adress.Text.Trim()+"',N'"+txt_store_mobile_1.Text.Trim()+"',N'"+txt_store_mobile_2.Text.Trim()+"',N'"+txt_store_Manger.Text.Trim()+"',N'"+txt_store_Details.Text.Trim()+"')");
cmd.Connection = con;
cmd.ExecuteNonQuery();
cmd.Parameters.AddWithValue("@store_name", txt_store_name.Text.Trim());
cmd.Parameters.AddWithValue("@store_adress", txt_store_adress.Text.Trim());
cmd.Parameters.AddWithValue("@store_mobile_1", txt_store_mobile_1.Text.Trim());
cmd.Parameters.AddWithValue("@store_mobile_2", txt_store_mobile_2.Text.Trim());
cmd.Parameters.AddWithValue("@store_manger", txt_store_Manger.Text.Trim());
cmd.Parameters.AddWithValue("@store_details", txt_store_Details.Text.Trim());
cmd.Parameters.AddWithValue("@Id_store", txt_store_number.Text.Trim());
con.Close();
lbl_store.Text="insert is sucess";
//cmd.Parameters.Add("@store_name", SqlDbType.NVarChar, 50).Value = txt_store_name.Text.Trim();
}