Inserting data after checking if table is empty - c#

I have a server program that will store certain data sent by the client. One data is the client's hostname. The server will check if the hostname exist, if not then it will insert that new data. It should look like this.
hostname_id | hostname
------------------------
1 | Admin
2 | Guest_PC
3 | Bob_PC2
My problem is it won't store the newly inserted data. It keeps on returning zero but not storing anything. Here is my code.(Edited to correct version)
string constring = "Database=chtbuster;Data Source=localhost;User Id=root;Password=''";
string count1 = "SELECT COUNT(hostName) FROM chtbuster.hostnametable WHERE hostName=#machineName ";
using (MySqlConnection conDataBase = new MySqlConnection(constring))
{
MySqlCommand cmd1Database = new MySqlCommand(count1, conDataBase);
conDataBase.Open();
long count = (long)cmd1Database.ExecuteScalar();
if (count == 0)
{
string insert_ht = "INSERT INTO chtbuster.hostnametable(hostName) VALUES(#machineName);";
MySqlCommand cmd5Database = new MySqlCommand(insert_ht, conDataBase);
cmd5Database.Parameters.AddWithValue("#machineName", machineName);
cmd5Database.ExecuteNonQuery();
//*test* output.Text += "\n Empty " + count;
}
else
{
//not empty, insert other data
}
}
I have coded PHP database before and is new to C# database, I'm quite confused. Please help. Thank you.

You can do this in one step with EXISTS:
IF NOT EXISTS (SELECT hostName FROM chtbuster.hostnametable WHERE hostName=#machineName)
INSERT INTO chtbuster.hostnametable(hostName_id) VALUES(#machineName);
As mentioned in the comments, you need to execute the query to get a result.

Related

How to count all rows in a data table c#

So I am creating a messaging application for a college project and I have a database of Users in Access, I have linked the database correctly and can execute statements but I am struggling with one problem, how to count the number of rows in a data table.
In fact, all I want to do is to count the total number of users and my teacher told me to get the data into a DataTable and count the number of rows. However, no matter how many users I have in the database, it always returns as 2.
int UserCount = 0;
using (OleDbConnection cuConn = new OleDbConnection())
{
cuConn.ConnectionString = #"DATASOURCE";
string statement = "SELECT COUNT(*) FROM Users";
OleDbDataAdapter da = new OleDbDataAdapter(statement, cuConn);
DataTable Results = new DataTable();
da.Fill(Results);
if (Results.Rows.Count > 0)
{
UserCount = int.Parse(Results.Rows[0][0].ToString());
}
}
The above code is a copy of what I was sent by my teacher who said it would work. Any help would be appreciated.
Also, sorry if this is a waste of time, still getting used to this StackOverflow thing...
Try replace Users with [Users]?
Because Users may be a key word of database.
Also the simpler way to get aggregate numbers is by ExecuteScalar method.
using (OleDbConnection cuConn = new OleDbConnection())
{
cuConn.ConnectionString = #"DATASOURCE";
string statement = "SELECT COUNT(*) FROM [Users]";
OleDbCommand cmd = new OleDbCommand (statement, cuConn);
cuConn.Open();
int count = (int)cmd.ExecuteScalar();
if (count > 0)
{
//
}
}
I successfully used your exact code (except the connection string) with sql server so maybe there is a problem with your #"DATASOURCE" or MS Access.

Getting column information in SQL

I am somwhat new to SQL, so I am not sure I am going about this the right way.
I am trying to fetch data from my SQL Server database where I want to find out if checkedin is 1/0, but it needs to search on a specific user and sort after the newest date as well.
What I am trying to do is something like this:
string connectionString = ".....";
SqlConnection cnn = new SqlConnection(connectionString);
SqlCommand checkForInOrOut = new SqlCommand("SELECT CHECKEDIN from timereg ORDER BY TIME DESC LIMIT 1 WHERE UNILOGIN = '" + publiclasses.unilogin + "'", cnn);
So my question, am I doing this right? And how do I fetch the data collected, if everything was handled correctly it should return 1 or 0. Should I use some sort of SqlDataReader? I am doing this in C#/WPF
Thanks
using (SqlDataReader myReader = checkForInOrOut.ExecuteReader())
{
while (myReader.Read())
{
string value = myReader["COLUMN NAME"].ToString();
}
}
This is how you would read data from SQL, but i recommend you looking into Parameters.AddWithValue
There are some errors in your query. First WHERE goes before ORDER BY and LIMIT is an MySql keyword while you are using the Sql Server classes. So you should use TOP value instead.
int checkedIn = 0;
string cmdText = #"SELECT TOP 1 CHECKEDIN from timereg
WHERE UNILOGIN = #unilogin
ORDER BY TIME DESC";
string connectionString = ".....";
using(SqlConnection cnn = new SqlConnection(connectionString))
using(SqlCommand checkForInOrOut = new SqlCommand(cmdText, cnn))
{
cnn.Open();
checkForInOrOut.Parameters.Add("#unilogin", SqlDbType.NVarChar).Value = publiclasses.unilogin;
// You return just one row and one column,
// so the best method to use is ExecuteScalar
object result = checkForInOrOut.ExecuteScalar();
// ExecuteScalar returns null if there is no match for your where condition
if(result != null)
{
MessageBox.Show("Login OK");
// Now convert the result variable to the exact datatype
// expected for checkedin, here I suppose you want an integer
checkedIN = Convert.ToInt32(result);
.....
}
else
MessageBox.Show("Login Failed");
}
Note how I have replaced your string concatenation with a proper use of parameters to avoid parsing problems and sql injection hacks. Finally every disposable object (connection in particular) should go inside a using block

Can't delete data with condition in SQL Server Compact Edition

I'm working with SQL Server Compact Edition. I try to delete data from the database on max date, I try on query it works perfectly, but when I execute in my program, turn to delete all data not base on query I have created.
Here is my code
string sqlCom="";
sqlCom = " delete from " + tableName; ;
sqlCom += " where messageid not in(";
sqlCom += " select messageid from tabmessageinclient";
sqlCom += " where convert(nvarchar(10),dtmessagetime,101) ";
sqlCom += " in (select max(convert(nvarchar(10),dtmessagetime,101)) from tabmessageinclient ))";
SqlCeConnection ceCon = new SqlCeConnection(Properties.Settings.Default.MyConnection);
if (ceCon.State == System.Data.ConnectionState.Open)
{ ceCon.Close(); }
ceCon.Open();
SqlCeCommand cmd = new SqlCeCommand();
cmd.Connection = ceCon;
cmd.CommandText = sqlCom;
cmd.ExecuteNonQuery();
does anyone know what wrong with my code, sorry for bad english
I would suggest firing all sub queries separately once to confirm that those sub queries return the correct set of data. i.e. in Following order
select max(convert(nvarchar(10),dtmessagetime,101)) from tabmessageinclient
select messageid from tabmessageinclient where convert(nvarchar(10),dtmessagetime,101) in (select max(convert(nvarchar(10),dtmessagetime,101)) from tabmessageinclient)
If this returns an expected data set, then verify if the second command gives any null values for messageid. When we use not in, it tends to not bring back anything if any of the selection value is null. In which case it would be better to use another and condition in your subquery.
where messageid is not null
You can read more about this behavior on SQL NOT IN not working
Just curious if there's any particular reason for using string concat? You may also want to use verbatim string (and string format), just so that your query is more legible.
string sqlComm = string.format(#"delete from {0} where messageid not in
(select messageid from tabmessageinclient where convert(nvarchar(10),dtmessagetime,101) in
(select max(convert(nvarchar(10),dtmessagetime,101)) from tabmessageinclient))", tableName);

No results on MySql Select after an Update using a MySqlDataAdapter with a MySqlCommandBuilder

I have the following code that is meant to simply test and try to resolve an issue I'm having where MySQL appears to return no results immediately when attempting to select a record after another record has just been updated. I've tried creating all new objects without using a loop just to make sure something wasn't still in scope. I've tried adding Thread.Sleep(3000) between loop iterations to see if that would help. So far it's been consistent, the first select and update commands are successful, and the next select fails immediately.
If, however, I remove the update, the Select works on the second iteration.
for (int orderId = 1; orderId <= 2; orderId++)
{
string sql = "SELECT * FROM tblOrder WHERE orderId = " + orderId;
var conn = GetConnection(); //Returns a new connection instance
var cmd = new MySqlCommand(sql, conn);
var da = new MySqlDataAdapter(cmd);
var cb = new MySqlCommandBuilder(da);
var orderDataTable = new DataTable();
da.Fill(orderDataTable);
if (orderDataTable.Rows.Count == 0)
throw new Exception("Order ID [" + orderId + "] not found.");
Console.Write("Order ID [ " + orderId + "] was found...");
orderDataTable.Rows[0]["notes"] = orderDataTable.Rows[0]["notes"].ToString() + " ";
da.Update(orderDataTable);
Console.Write("Update Test Passed\r\n");
}
GetConnection looks like this...
private const string ConnectionString = "myConnectionString";
public static MySqlConnection GetConnection()
{
return new MySqlConnection(ConnectionString);
}
Should go without saying, but I've definitely checked to make sure the orderId I'm selecting is there.
I believe the issue has something to do with MySql locking mechanisms, but I'm more of a SQL Server guy so I'm not terribly familiar with the peculiarities of MySql. I tried changing the SELECT to end with "FOR UPDATE" and that did not seem to help.
Update: Writing my own update statement and using a separate MySqlCommand object works, but is not preferred since my actual code updates a lot of fields and logic and I would prefer not to have to form the update statement within that logic.

in C# OleDbDataAdapter.fill method not giving any data or error

I am using a data adapter to pull data from an access database (see below code). When I run the SQL in the Access database I get the expected data. However when I step through the code the fill method produces only the table definition but no rows.
I have used this procedure many times in the past and it still works for those calls.
Again the SQL in access returns the correct data and in C# I don't get ANY error message but I don't get the data either. Had anyone seen this before?
`
public void GetQueries(ref DataTable tSQL, String tool, string Filter, OleDbConnection lConn)
{
OleDbDataAdapter dadapt = new OleDbDataAdapter(); //Data Adapter for Access
String lSQL = "";
//assign the connection to the processing mdb
//lAccProcSQL.Connection = lConn;
//Pull the queries to be executed
lSQL = "SELECT * FROM tblSQL WHERE Active = TRUE AND ToolCode = '" +
tool + "' and type not in (" + Filter + ") ORDER BY QueryNum";
//Set the adapter to point to the tblSQL table
dadapt = new OleDbDataAdapter(lSQL, lConn);
//clear tables in case of rerun
tSQL.Clear();
//Fill working queries data table
dadapt.Fill(tSQL);
}`
Are you sure that the filter that you've defined in the WHERE clause will evaluate to true on certain rows ?
Why don't you use parameters instead of string concatenation ? Are you sure that Active = True will evaluate to true ? As far as I know, True is represented by -1 in Access.
So, why don't you try it like this:
var command = new OleDbCommand();
command.Connection = lConn;
command.CommandText = "SELECT * FROM tblSql WHERE Active = -1 AND ToolCode = #p_toolCode AND type NOT IN (" + filter + ") ORDER BY querynum";
command.Parameters.Add ("#p_toolCode", OleDbType.String).Value = tool;
datapt = new OleDbDataAdapter();
datapt.SelectCommand = command;
dadapt.Fill (tSql);

Categories