【问题标题】:Tracing error in database跟踪数据库中的错误
【发布时间】:2016-01-01 12:17:41
【问题描述】:

我有一个客户端服务器程序,服务器会检查客户端是否打开了正确的应用程序。如果没有,那么它将显示一些警告。它应该只打开三个应用程序以及正确的一个。我打算将打开的应用程序的数据和用户主机名放入数据库。将有两个表,主机名表和进程表。 示例:

主机名表

hostname_id | hostname
------------------------
      1     | Guest1
      2     | Guest2
      3     | Guest3

处理表

id | processID | processName | processExe | processPath     | hostname_id
--------------------------------------------------------------------------
1  |    4332   |  C# Basic   |  adobe.exe | C:/Users/Adm... |      2      
2  |    5400   |  PHP 101    |  ppt.exe   | C:/Users/Adm... |      2      
3  |    0943   |  Notice     |notepad.exe | C:/Users/Adm... |      1      
4  |    8932   |  Java 101   |  adobe.exe | C:/Users/Adm... |      3      
5  |    7608   |  Certific   |  word.exe  | C:/Users/Adm... |      1      
6  |    0101   |  Aliens     |  ppt.exe   | C:/Users/Adm... |      1      
7  |    8200   |  Progress   |  excel.exe | C:/Users/Adm... |      3   

一旦客户端打开一个新的应用程序,[hostname,processID,processName, processExe, processPath] 将在服务器中发送。服务器将

-通过获取主机名计数检查主机名是否存在,

-如果是,那么它将选择 hostname_id 和

-将其与其他数据一起插入新表中。

如果没有

-然后在主机名表中插入一个新的主机名

-它会选择hostname_id

-插入数据

这是一个一对多的关系,所以在后面的部分我需要检索它以进行输出显示和验证。 我的问题是我已经逐步调试了代​​码的数据库部分,但是当我将它们作为一个整体运行时,它会在过程的最后发现一个错误。在这里它会自动转到

catch { output.Text += "\nERROR THREE\n "; }

这是我的代码。

 using (MySqlConnection conDataBase = new MySqlConnection(constring))
            {
                try
                {
                    if (exeFile == openedFile)
                    {
                        listBox1.ForeColor = System.Drawing.Color.Blue;
                        listBox1.Items.Add(machineName + " has opened the right file.");
                    }
                    else
                    {
                        string count1 = "SELECT COUNT(hostName) FROM hostnametable;";
                        string gethostname_id = "SELECT INTO chtbuster.hostnametable(hostName_id) WHERE hostName=?machineName";
                        string insert_pt = "INSERT INTO chtbuster.processtable(processID,processFileName,processName,processPath,hostName_id) VALUES (@processID, @fileName, @exeFile, @filePath, " + gethostname_id + ");";
                        string insert_ht = "INSERT INTO chtbuster.hostnametable(hostName_id) VALUES(@machineName);";
                        //query for else condition 1 is at the top

                        listBox1.ForeColor = System.Drawing.Color.Green;
                        listBox1.Items.Add(machineName + " has opened " + exeFile);
                        conDataBase.Open();

                        MySqlCommand cmd1Database = new MySqlCommand(count1, conDataBase);
                        cmd1Database.ExecuteNonQuery(); 

                        Int32 ifexist = (Int32)cmd1Database.ExecuteScalar();
                        if(ifexist>0)
                        {
                           MySqlCommand cmd2Database = new MySqlCommand(gethostname_id, conDataBase);
                            machineName = (string)cmd1Database.ExecuteScalar(); 
                            cmd2Database.Parameters.AddWithValue("?machineName", machineName);

                            MySqlCommand cmd3Database = new MySqlCommand(insert_pt, conDataBase);

                              try
                              {
                                  cmd3Database.Parameters.Clear();
                                  cmd3Database.Parameters.AddWithValue("@processID", processID);
                                  cmd3Database.Parameters.AddWithValue("@machineName", machineName);
                                  cmd3Database.Parameters.AddWithValue("@filename", fileName);
                                  cmd3Database.Parameters.AddWithValue("@exeFile", exeFile);
                                  cmd3Database.Parameters.AddWithValue("@filePath", filePath);
                                  cmd3Database.ExecuteNonQuery();
                                  cmd2Database.ExecuteReader();

                               }
                              catch (Exception ex)
                              {
                                  output.Text += "\n1" + (ex.Message);
                              } 
                        }

                        else
                        {
                           MySqlCommand cmd4Database = new MySqlCommand(Query, conDataBase);
                           MySqlCommand cmd5Database = new MySqlCommand(insert_ht, conDataBase);

                            try
                              {
                                  cmd5Database.Parameters.Clear();
                                  cmd5Database.Parameters.AddWithValue("@processID", processID);
                                  cmd5Database.Parameters.AddWithValue("@machineName", machineName);
                                  cmd5Database.Parameters.AddWithValue("@filename", fileName);
                                  cmd5Database.Parameters.AddWithValue("@exeFile", exeFile);
                                  cmd5Database.Parameters.AddWithValue("@filePath", filePath);
                                  cmd4Database.Parameters.AddWithValue("@machineName", machineName);
                                  cmd4Database.ExecuteNonQuery();
                                  cmd5Database.ExecuteNonQuery();
                                  conDataBase.Close();

                               }
                            catch (Exception ex)
                            {
                                output.Text += "\n2" + (ex.Message);
                            } 
                      }    
                    }

                }
                catch (Exception ex)
                {
                    output.Text += "\n3" + (ex.Message);
                } 
            }

【问题讨论】:

  • 所以您实际上并不想查看异常是什么?只是发生了某事?如果我们不知道导致它的异常是什么,就很难确定为什么会发生“错误三”。
  • 你也有一个逻辑错误,如果我没看错的话:你在cmd3Database.ExecuteNonQuery之后关闭conDataBase,但是你稍后尝试运行cmd1Database.ExecuteNonQuery,然后再次关闭conDataBase .它已经关闭了。
  • 正如@Ann L. 所说,您正试图多次关闭 conDataBase 连接。这将引发异常。将来,我建议您在遇到问题时捕获(Exception ex),然后(至少)在此处发布异常消息。当您知道异常是什么时,就更容易了解导致异常的原因。
  • @AnnL。感谢您及时的回复。我已经编辑了我的代码并放置了 catch (Exception ex),它给了我“指定的演员表无效”。在第三次捕获。我该如何解决这个问题?
  • “指定的演员阵容无效。”可能在 ExecuteScalar()

标签: c# mysql .net database one-to-many


【解决方案1】:

首先,我认为你还有一个逻辑问题:

 MySqlCommand cmd1Database = new MySqlCommand(count1, conDataBase);
 cmd1Database.ExecuteNonQuery(); 

 Int32 ifexist = (Int32)cmd1Database.ExecuteScalar();
 if(ifexist>0)
 {
       MySqlCommand cmd2Database = new MySqlCommand(gethostname_id, conDataBase);
       machineName = (string)cmd1Database.ExecuteScalar(); 

自第一次运行cmd1Database 以来,您还没有更改过CommandText 属性。所以它将运行相同的查询,即count1 中指定的查询。

这将返回一个Int32。这不能直接转换为string,就像您对(string)cmd1Database.ExecuteScalar(); 所做的那样。

关于“指定的演员表无效”:

现在,我不知道MySqlCommand 的怪癖。但这里引用了文档中的一段话,我认为它是基类(.NET 的 System.Data.Common.DbCommand):

如果没有找到结果集中第一行的第一列,则 返回空引用(在 Visual Basic 中为 Nothing)。如果值在 数据库为空,查询返回 DBNull.Value。

(source)

根据导致问题的ExecuteScalar,您可能面临略有不同的情况。如果没有返回行,您的ExecuteScalar 将返回Null。这不能转换为Int32。你必须这样处理它:

 int rowCount = 0;
 object result = cmd1Database.ExecuteScalar();
 if(result != null)
 {
     rowCount = (Int32) result;
 }

如果有数据,但数据库中的值为Null,则返回的值将是比较奇特的类型DBNull。这不会转换为任何其他类型(Object 除外)。所以你最终会做这样的事情:

 object result = cmd1Database.ExecuteScalar(); 
 if(!DBNull.Value.Equals(result))
 {
      machineName = (string) result;
 }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-07
    • 2018-07-07
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    相关资源
    最近更新 更多