在连接字符串方面需要帮助

PDS8475

活跃的成员
已加入
2019年6月25日
留言内容
41
编程经验
Beginner
你好
我有一个访问数据库的连接字符串,该数据库正在从文件读取它的路径。
连接字符串和SQL查询的代码是

C#:
            string ConString = System.IO.File.ReadAllText("FixIT.con");
            ConString = ConString.Replace(System.Environment.NewLine, string.Empty);
            string FullString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ConString;
            System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
            conn.ConnectionString = FullString;
            OleDbCommand cmd = new OleDbCommand("INSERT into Donations (Name, Address, Phone, 电子邮件, DateDonated, Type, Make, Model, Notes, EnteredBy) Values(@n, @a, @p. @em, @d, @i,            @IT, @m, @MO, @s, @NO)");
            
        
             try
            {
                conn.Open();
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed to connect to data source");
            }
            finally
            {
                conn.Close();
            }

我可以看到连接字符串"FullString" is
"Provider = Microsoft.ACE.OLEDB.12.0;数据源= C:\\ Users \\ Paul \\ Documents \\ FixIT.mdb"

但是我只收到消息框,说无法连接到数据源。同样,检查数据库文件显示未输入任何记录。

我不明白为什么这不会连接。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,499
地点
悉尼,澳大利亚
编程经验
10+
当然,这就是您得到的信息。这就是您要显示的消息。您实际上应该在检查异常,以查看问题所在。

The issue is fairly obvious though. You have 11 parameter placeholders in your SQL code but you don;t add any parameters to the command. Where's the data supposed to be coming from? That means that the issue actually has nothing at all to do with the connection string and it's the ExecuteNonQuery that's failing rather than the Open. That's why you need to actually look at the information the debugger provides you with.
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,921
地点
英国
编程经验
10+
我认为这是错误的,您可以改进。
  1. 您怎么知道这反映了一条道路?您要读取的文件,文本文件的位置在哪里,为什么不使用常规做法进行路径构建? string ConString = System.IO.File.ReadAllText("FixIT.con");
  2. 为什么不将连接字符串的内容放在引号中,而让constring等于?
  3. 为什么要从文件中读取连接字符串?
  4. 您不需要使用字符串。如果您的项目符号为2,请替换
  5. 像这样将字符串串在一起确实是一个坏习惯,您应该使用string.Concat代替 string FullString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ConString;
  6. 同样,请参考项目符号2,并将整个连接字符串放在一个字符串中。
  7. 您没有在命令语句后传递连接字符串 OleDbCommand cmd = new OleDbCommand("INSERT into Donations (Name, Address, Phone, 电子邮件, DateDonated, Type, Make, Model, Notes, EnteredBy) Values(@n, @a, @p. @em, @d, @i, @IT, @m, @MO, @s, @NO)");
  8. 在项目符号7上,您还将传递10个值,并提供11个参数,包括后面的错字 @p.
  9. 同样在项目符号7上,您不能在参数占位符旁边指定任何参数值。 (@p,值)
  10. 如果存在,则无需打开连接 也许 一个已经打开。您应该先检查一下。
  11. 您在这里不需要使用块就足够了,尤其是在您的命令上。使用块是自动配置的,您可以在我的签名中找到指向该块的链接。
  12. catch (Exception ex) 如果在例外框中输出自定义消息,您如何知道实际抛出了哪个例外? ex例外涵盖了一系列例外。最好让显式异常带有多个catch {}块,以捕获您代码可能抛出的不同异常的范围。然后,如果未抛出所有其他异常,则可以将ex ex添加为要捕获的最后一个异常。

以下是项目符号12的示例,仅作为示例。捕获异常不是捕获和忽略错误,而是捕获错误和故障,并为您提供纠正或相应处理错误的机会。
C#:
            catch (OleDbException dbex)
            {

            }
            catch (OverflowException ofe)
            {

            }
            catch (Exception ex) /* if the above exceptions aren't thrown, the below one will catch all others. Each exception of which ever exceptions you want to catch should be handled separately and not all in one base exception block like below */
            {
                MessageBox.Show("Failed to connect to data source");
            }

希望这些建议对您有所帮助。您可能想阅读一下 Exception.Message属性(系统) 和这个 异常类(系统)
 

PDS8475

活跃的成员
已加入
2019年6月25日
留言内容
41
编程经验
Beginner
谢谢,我重写了代码,也重写了消息框以给出异常


C#:
private void Save_button_Click(object sender, EventArgs e)
        {
          

            string ConString = System.IO.File.ReadAllText("FixIT.con");
            ConString = ConString.Replace(System.Environment.NewLine, string.Empty);
            System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
            conn.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" + @"Data Source=" + ConString;
          
            
            try
            {
                string n = Name_textBox.Text;
                string a = Address_textBox.Text;
                string p = Phone_textBox.Text;
                string em = 电子邮件_textBox.Text;
                string d = Date_textBox.Text;
                string i = EnteredBy_textBox.Text;
                string IT = Type_cmbBx.Text;
                string m = Make_textBox.Text;
                string MO = Model_textBox.Text;
                string s = Serial_textBox.Text;
                string NO = Notes_textBox.Text;

                conn.Open();
                String my_querry = "INSERT INTO Donations (Name, Address, Phone, 电子邮件, DateDonated, Type, Make, Model, Serial, Notes, EnteredBy) Values(@n, @a, @p, @em, @d, @IT, @m, @MO, @s, @NO, @i)";
                OleDbCommand cmd = new OleDbCommand(my_querry, conn);
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Failed due to " + ex.Message);
            }
            finally
            {
                conn.Close();
            }
        }

如果我在OleDbCommand cmd = new OleDbCommand(my_querry,conn)的行上放置一个断点,现在好像正在连接。
它指出conn在visual studio的Autos部分中打开
但是它抛出了异常

由于未提供一个或多个必需参数的值而失败

我查看了我的查询,并且字段的数量与值相同。数据库中所有字段的名称均相同,并且顺序相同。数据库中的字段也设置为不需要。

我不知道是什么原因导致此错误
 

PDS8475

活跃的成员
已加入
2019年6月25日
留言内容
41
编程经验
Beginner
我认为这是错误的,您可以改进。
  1. 您怎么知道这反映了一条道路?您要读取的文件,文本文件的位置在哪里,为什么不使用常规做法进行路径构建? string ConString = System.IO.File.ReadAllText("FixIT.con");
  2. 为什么不将连接字符串的内容放在引号中,而让constring等于?
  3. 为什么要从文件中读取连接字符串?
  4. 您不需要使用字符串。如果您的项目符号为2,请替换
  5. 像这样将字符串串在一起确实是一个坏习惯,您应该使用string.Concat代替 string FullString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ConString;
  6. 同样,请参考项目符号2,并将整个连接字符串放在一个字符串中。
  7. 您没有在命令语句后传递连接字符串 OleDbCommand cmd = new OleDbCommand("INSERT into Donations (Name, Address, Phone, 电子邮件, DateDonated, Type, Make, Model, Notes, EnteredBy) Values(@n, @a, @p. @em, @d, @i, @IT, @m, @MO, @s, @NO)");
  8. 在项目符号7上,您还将传递10个值,并提供11个参数,包括后面的错字 @p.
  9. 同样在项目符号7上,您不能在参数占位符旁边指定任何参数值。 (@p,值)
  10. 如果存在,则无需打开连接 也许 一个已经打开。您应该先检查一下。
  11. 您在这里不需要使用块就足够了,尤其是在您的命令上。使用块是自动配置的,您可以在我的签名中找到指向该块的链接。
  12. catch (Exception ex) 如果在例外框中输出自定义消息,您如何知道实际抛出了哪个例外? ex例外涵盖了一系列例外。最好让显式异常带有多个catch {}块,以捕获您代码可能抛出的不同异常的范围。然后,如果未抛出所有其他异常,则可以将ex ex添加为要捕获的最后一个异常。

以下是项目符号12的示例,仅作为示例。捕获异常不是捕获和忽略错误,而是捕获错误和故障,并为您提供纠正或相应处理错误的机会。
C#:
            catch (OleDbException dbex)
            {

            }
            catch (OverflowException ofe)
            {

            }
            catch (Exception ex) /* if the above exceptions aren't thrown, the below one will catch all others. Each exception of which ever exceptions you want to catch should be handled separately and not all in one base exception block like below */
            {
                MessageBox.Show("Failed to connect to data source");
            }

希望这些建议对您有所帮助。您可能想阅读一下 Exception.Message属性(系统) 和这个 异常类(系统)

您好在回答问题3
数据库文件将不在该程序所在的PC上。因此,我在另一种表单上创建了一个按钮,该按钮仅在某些人登录后才启用或可见,这将打开一个打开文件对话框,以便管理员可以选择数据库的路径,然后将该路径存储在FixIT.con文件中。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,921
地点
英国
编程经验
10+
您的错误是由于此::
同样在项目符号7上,您不能在参数占位符旁边指定任何参数值。 (@p,值)
如果我不清楚,请参见以下示例。看一下此链接上的第四个片段,您是否看到我如何使用参数:: 与SQL Server的表单连接

注意:该示例适用于MySQL,但是参数的使用或多或少相同。
 

PDS8475

活跃的成员
已加入
2019年6月25日
留言内容
41
编程经验
Beginner
您的错误是由于此::

如果我不清楚,请参见以下示例。看一下此链接上的第四个片段,您是否看到我如何使用参数:: 与SQL Server的表单连接

注意:该示例适用于MySQL,但是参数的使用或多或少相同。

您将不得不原谅我中风,因此尝试集中精力一段时间后我的头变得非常模糊。明天清醒一下,我看看。
谢谢您的帮助
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,921
地点
英国
编程经验
10+
在此行之前:: cmd.ExecuteNonQuery();
您需要添加参数::
C#:
                        cmd.Parameters.AddWithValue("@n", Your string here);
                        cmd.Parameters.AddWithValue("@a", Your string here);
                        cmd.Parameters.AddWithValue("@p", Your string here);
                        cmd.Parameters.AddWithValue("@em", Your string here);

依此类推.....如上文所述,添加命令查询中其余的参数占位符,然后再次尝试执行。您显然需要用您要从假定的UI中插入的值替换此处的Your字符串。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,499
地点
悉尼,澳大利亚
编程经验
10+
C#:
conn.ConnectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" + @"Data Source=" + ConString;
逐字字符串文字(即以'@'开头的字符串文字)的要点是允许您包含反斜杠而不必对其进行转义。您的文字中没有反斜杠-文件路径包含在变量中-因此逐字字符串文字毫无意义。除非您需要逃避其他事情,否则它不会造成伤害,但是不会有所帮助。同样,也没有理由将两个文字串联在一起。
 
Last edited:

PDS8475

活跃的成员
已加入
2019年6月25日
留言内容
41
编程经验
Beginner
Before this line :: cmd.ExecuteNonQuery();
您需要添加参数::
C#:
                        cmd.Parameters.AddWithValue("@n", Your string here);
                        cmd.Parameters.AddWithValue("@a", Your string here);
                        cmd.Parameters.AddWithValue("@p", Your string here);
                        cmd.Parameters.AddWithValue("@em", Your string here);

依此类推.....如上文所述,添加命令查询中其余的参数占位符,然后再次尝试执行。您显然需要用您要从假定的UI中插入的值替换此处的Your字符串。
谢谢,它现在可以完美运行了。愚蠢的是,昨晚我的大脑没有看到线条。今天早晨,我打开了一个昨晚使用的示例网站,代码示例中的代码行就在那里。
 

PDS8475

活跃的成员
已加入
2019年6月25日
留言内容
41
编程经验
Beginner
逐字字符串文字(即以'@'开头的字符串文字)的要点是允许您包含反斜杠而不必对其进行转义。您的文字中没有反斜杠-文件路径包含在变量中-因此逐字字符串文字毫无意义。除非您需要逃避其他事情,否则它不会造成伤害,但是不会有所帮助。同样,也没有理由将两个文字串联在一起。

谢谢,我现在已经从连接字符串中删除了@符号。我想知道它们是什么意思,但将它们包括在内,因为我一直在研究的示例都包含它们。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,921
地点
英国
编程经验
10+
所以我认为这次执行没有错误?

乐意效劳。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,499
地点
悉尼,澳大利亚
编程经验
10+
谢谢,我现在已经从连接字符串中删除了@符号。我想知道它们是什么意思,但将它们包括在内,因为我一直在研究的示例都包含它们。
这些示例将使用它们,因为它们在连接字符串中包括了文字文件路径,否则必须将斜杠转义。文件和文件夹路径是逐字字符串文字的最常见用法。
 
最佳 底部