我有一个客户端服务器程序,服务器检查客户端是否打开了正确的应用程序。如果没有,则会显示一些警告。它应该只打开三个应用程序和正确的应用程序。我打算将打开的应用程序和用户主机名的数据放入数据库。将有两个表,hostnametable和processtable。 例如:
hostnametable
hostname_id | hostname
------------------------
1 | Guest1
2 | Guest2
3 | Guest3
processtable
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和
- 将其与其他数据一起插入新表中。
如果不是
- 然后在主机名表中插入新主机名
-it将选择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);
}
}
答案 0 :(得分:0)
首先,我认为你还有一个逻辑问题:
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();
自您第一次运行CommandText
以来,您尚未更改cmd1Database
的{{1}}属性。因此,它将运行相同的查询,即count1
中指定的查询。
这将返回Int32
。这不能直接转换为string
,就像使用(string)cmd1Database.ExecuteScalar();
一样。
现在,我不知道MySqlCommand
的怪癖。但是这里引用了文档中我假设的基类(.NET' s System.Data.Common.DbCommand
):
如果未找到结果集中第一行的第一列,则a 返回null引用(在Visual Basic中为Nothing)。如果值在 数据库为null,查询返回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;
}