【问题标题】:"Exception Unhadled" error during SqlConnection open()SqlConnection open() 期间出现“异常未处理”错误
【发布时间】:2018-02-07 16:23:30
【问题描述】:

在我的程序中,我有两个文本输入字段(以 Windows 形式)和一个用于将这些值添加/保存到 DB 表中的按钮。问题是,一旦我单击按钮,它就不会将输入插入数据库,而是显示我在下面附加的错误图像。

我的程序有什么问题?

我的工作代码:

public partial class Form1 : Form
{
    //original Connection string is exactly the following:
    //Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename="C:\Users\Sanad Al Nahaj\Documents\thesaurus.mdf";Integrated Security=True;Connect Timeout=30
    SqlConnection conn = new SqlConnection(@"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\Sanad Al Nahaj\Documents\thesaurus.mdf;Integrated Security = True; Connect Timeout = 30");
    public Form1()
    {
        InitializeComponent();
    }

    //Save button
    private void button1_Click(object sender, EventArgs e)
    {
        conn.Open();//error pops up here after clicking the button
        SqlCommand command = conn.CreateCommand();
        command.CommandType = CommandType.Text;
        command.CommandText = "insert into Table values('"+wordbox.Text+"','"+synonymbox.Text+"')";
        command.ExecuteNonQuery();
        conn.Close();
        MessageBox.Show("Word and Synonym added!");
    }

    private void display_Click(object sender, EventArgs e)
    {
        //implement
    }
}

错误:

数据库如下:


更新: 我对Using模式的修改(参考CDove的回答):

    var command = new SqlCommand();
            using (command = new SqlCommand(
                          "insert into......)
))

【问题讨论】:

  • 所述文件已附加
  • 我想我看到了一个问题:您没有正确处理连接。将连接作为类比例变量保持打开的整个模式是一个坏主意。创建。采用。处置。这是处理一次性物品的唯一方法 (docs.microsoft.com/en-us/dotnet/csharp/language-reference/…)。不要担心性能。 SQLConenction 本身可能会做一些连接池。最后,无故障运行程序优先。
  • 您能否尝试在您的 web.config 文件中执行:,然后重试。
  • Eray Balkanli,你的意思是在我的 web.config 文件中吗?在这种情况下,它应该在 标签内吗?
  • 我的意思是相关应用程序的 web.config 文件。相信你会在Visual Studio的项目下看到它

标签: c# sql visual-studio sqlconnection


【解决方案1】:

您需要做四件事。首先,解决这个问题:

"insert into [Table] values('"+wordbox.Text+"','"+synonymbox.Text+"')"

如果我没记错的话,在 Microsoft SQL 中,插入时的 values() 语法需要首先明确声明列。此外,“Table”是一个保留字,因此您需要将其放在括号中才能将该词用作表名。将来,请避免在表模式中使用保留字。

"insert into [Table] (word, synonym) values ('"+wordbox.Text+"','"+synonymbox.Text+"')"

第二,don't use string concatenation to build a query。而是创建参数。

"insert into [Table] (word, synonym) values (@word,@syn)"

然后

 command.Parameters.AddWithValue("@word", wordbox.Text); 
 command.Parameters.AddWithValue("@syn", synonymbox.Text);
 command.ExecuteNonQuery();

第三,不要缓存你的连接。这就是它在代码顶部的作用,为您留下一个必须进行微观管理的连接:

SqlConnection conn = new SqlConnection(@"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\Sanad Al Nahaj\Documents\thesaurus.mdf;Integrated Security = True; Connect Timeout = 30");

虽然理想情况下,您应该从 web.config 或 app.config 中读取此内容,但我们将使用您的硬编码字符串;只留下一个字符串。

string conn = @"Data Source = (LocalDB)\MSSQLLocalDB; AttachDbFilename=C:\Users\Sanad Al Nahaj\Documents\thesaurus.mdf;Integrated Security = True; Connect Timeout = 30";   

最后,使用using 模式。这不仅是不那么臭的代码,而且还以隐含的try-finally 方式包含了隐含的.Close().Dispose()

private void button1_Click(object sender, EventArgs e)
{
    using(var command = new SqlCommand(
             "insert into [Table] (word, synonym) values (@word,@syn)",
              new SqlConnection(conn)
          ))
    {
       command.Connection.Open();//Since we aren't reopening an old connection, errors are less likely.    
       command.CommandType = CommandType.Text;
       command.Parameters.AddWithValue("@word", wordbox.Text); 
       command.Parameters.AddWithValue("@syn", synonymbox.Text);                   

       if(command.ExecuteNonQuery() > 0 )
           MessageBox.Show("Word and Synonym added!");
    }
}

请注意,我检查了ExecuteNonQuery 的值。那是因为这个函数返回受影响的行数;如果计数为 0,则不添加单词和同义词。

注意:这完全是我午休时的想法,所以请自己测试一下,看看效果如何。

【讨论】:

  • Table 是保留字,我相信,所以它需要放在括号中。
  • 好电话。我会把它添加到答案中。
  • 感谢您的回答,但我不清楚“使用”模式。整个代码块是否应该放在 button_click 方法中?能否请您立即格式化并编写整个更正的代码,以免我感到困惑。
  • usings 绕过专门使用该对象的代码块。它们是一种使用继承IDisposable 的对象的方法。在示例中,您只需将调用数据库的代码包装在 using 块中,并以如图所示的方式声明您的命令对象。在这种情况下,它确实都在button_click 事件处理程序中。您可能希望将字符串与您已经拥有的类级别的连接作为SqlConnection,这样您就可以在整个类中访问该字符串。
  • 另一件事... - 我怀疑您的使用会关闭与数据库的连接。 - 您只处理 SqlCommand 而不是连接,我怀疑处理 SqlCommand 是否会处理 SqlConnection,因为 SqlCommand 无法知道 SqlConnection 是否像您一样被传递到构造函数中,或者它是否是范围之外的变量. --- 我建议使用以下语法using (var sqlConnection = new SqlConnection(con)) { sqlConnection.Open(); using (var sqlCommand = sqlConnection.CreateCommand) { //do stuff } }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-05
相关资源
最近更新 更多