C# Variable scope in switch statement - c#

I have a function that begins with this:
void RecordLoadPosition()
{
OdbcCommand command;
if (_hasPlantGenie)
{
command = new OdbcCommand();
string query;
switch (ItemType)
{
case ItemTypeEnum.COIL:
// We're only going to add records to the coils_pg table when the coil gets moved. After
// a record is added, we'll update it.
command = new OdbcCommand("select * from coils_pg where coil_id = " + _itemName, _db);
When I compile this, I do not get an error on the first line in the if block, but I get errors complaining that I cannot use "command" before it is declared inside the case block. I don't understand why the declaration at the top of the function is not available inside the case block.
But OK. If it's not visible in the case block, I can just declare it. I changed the first statement in the case block to "OdbcCommand command...". Now I get an error complaining that I can't declare a variable that is already declared in a parent block! I can't win either way!
What is happening here?
Of course, I can just use different OdbcCommand objects, and that's what I'll do for now, but I'd like to understand this.
=============================================
It does appear that something is missing in my original code sample, but I have no idea what. Here is a small function that should have shown the same error, but did not:
void ScopeTest()
{
OdbcCommand command = null;
if (_hasPlantGenie)
{
command = new OdbcCommand();
switch (ItemType)
{
case ItemTypeEnum.COIL:
// We're only going to add records to the coils_pg table when the coil gets moved. After
// a record is added, we'll update it.
command = new OdbcCommand();
break;
}
}
}
==============================================
And, because people asked for it, here is the complete original function (including the extra creation of an OdbcCommand object at the top of the if block merely to demonstrate that it does not throw an error:
void RecordLoadPosition()
{
OdbcCommand command = null;
if (_hasPlantGenie)
{
command = new OdbcCommand();
string query;
switch (ItemType)
{
case ItemTypeEnum.COIL:
// We're only going to add records to the coils_pg table when the coil gets moved. After
// a record is added, we'll update it.
command = new OdbcCommand("select * from coils_pg where coil_id = " + _itemName, _db);
OdbcDataReader reader = command.ExecuteReader();
if (reader.Read())
{
query = "update plant_genie.coils_pg set x_coordinate = " +
XPosCurrent.ToString() +
", y_coordinate = " +
YPosCurrent.ToString() +
" where coil_id = '" +
_itemName + "'";
reader.Close();
command.CommandText = query;
command.ExecuteNonQuery();
}
else
{
query = "insert into plant_genie.coils_pg(coil_id, x_coordinate, y_coordinate) values (" +
XPosCurrent.ToString() + YPosCurrent.ToString() +
"'" + _itemName + "')";
reader.Close();
command.CommandText = query;
command.ExecuteNonQuery();
}
break;
case ItemTypeEnum.INNER_COVER:
// The inner_cover_pg table will be pre-built. We can assume that it has records for
// each inner cover.
query = "select set_inner_cover_down(" +
XPosCurrent.ToString() +
", " +
YPosCurrent.ToString() +
", '" +
_itemName +
"')";
OdbcCommand command = new OdbcCommand(query, _db);
command.ExecuteNonQuery();
// See if the cover has been set down in a storage location. If it has
break;
}
}
}

Inside your case ItemTypeEnum.INNER_COVER: condition, you have:
OdbcCommand command = new OdbcCommand(query, _db);
You're redeclaring it, when you should just be assigning it like you are in the case ItemTypeEnum.COIL: branch. Replace that line with this:
command = new OdbcCommand(query, _db);

Related

How to check if value already exists in database with c# for unity (error in SQL syntax)

I'm trying to get if a value already exists in my database for a registration and I've searched everywhere for an answer but I get this error:
" You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near...at line 1".
I don't know what I'm doing wrong...
void Start()
{
linhaConn = "Server=localhost;" +
"Database=jogo;" +
"User ID=root;" +
"Password=;" +
"Pooling=false;" +
"CharSet=utf8";
ConnDatabase(linhaConn);
}
void ConnDatabase(string lConn)
{
conn = new MySqlConnection(lConn);
conn.Open();
print("Conectado");
}
public void InserirDB()
{
ConnDatabase(linhaConn);
txtUser = InpUserCriar.text;
txtEmail = InpEmail.text;
command = new MySqlCommand("select * from jogador where ([email] = '" + txtEmail + "')", conn);
int UserExist = (int)command.ExecuteScalar();
if (UserExist > 0)
{
print("already exists");
}
else
{
print("doesnt exists");
}
conn.Close();
EDIT
I did it! Here is the code:
ConnDatabase(linhaConn);
txtUser = InpUserCriar.text;
txtEmail = InpEmail.text;
string countDataEmail;
command = new MySqlCommand("select count(*) from jogador where email= '" + txtEmail+ "' ;", conn);
countDataEmail = command.ExecuteScalar().ToString();
if (countDataEmail == "0")
{
print("it doesnt exist");
}
else
{
print("email already exists");
}
If you just want to check if they query returns ant row you can use UserExist.HasRows
I just wanted to mention SQL Injection! Whenever dealing with User Input make sure they can't harm or retrieve something from your database. See the example which uses a prepared statement to avoid that.
besides that, are you sure it should be
... where ([email] = some#email.address)
instead of (how I know SQL queries)
... where email = some#email.adddres;
So together it would probably be something like
command = new MySqlCommand("select * from jogador where email = #email;", conn);
command.Parameters.AddWithValue("#email", txtEmail);
commandPrepare();

Show data in Textboxes from database in C#

Is there anything wrong with my code? It is not showing data in textboxes. The same funtion is working for another table in database but not for this one.
private void metroButton1_Click(object sender, EventArgs e)
{
con = new SqlConnection(constr);
String query = "Select FROM Student WHERE Std_ID = '" + metroTextBox1.Text + "'";
cmd = new SqlCommand(query, con);
con.Open();
try
{
using (SqlDataReader read = cmd.ExecuteReader())
{
while (read.Read())
{
// metroTextBox1.Text = (read["ID"].ToString());
metroTextBox2.Text = (read["Name"].ToString());
metroTextBox3.Text = (read["F_Name"].ToString());
metroTextBox4.Text = (read["Std_Age"].ToString());
metroTextBox5.Text = (read["Address"].ToString());
metroTextBox6.Text = (read["Program"].ToString());
metroComboBox1.Text = (read["Course"].ToString());
}
}
}
finally
{
con.Close();
}
}
you need to give column names in the select statement or select *
for example :
String query = "Select * from Student WHERE Std_ID = '" + metroTextBox1.Text + "'";
Not related to Question: you can change the while loop to if condition if you have one record for given id. even there are many records for given id you will see the last record data only because of the while loop will overwrite the textboxes in every record.
Update :
There isn't anything wrong with Syntax because the same syntax is
working for modifying teacher funtion.
No, this is incorrect, remove the try catch in your code then you will see the exception of syntax error

C# MySQL Parameterized update returning nothing

Whenever I try to update my database, the result ends up being 0.
If I do it in HeidiSQL, it updates just fine, so I know it's not the query.
I have my suspicion that it has to do with the parameters, but I'm unsure regarding that.
I tried with both # and ?, but neither have worked.
MySqlCommand Command = new MySqlCommand("UPDATE `users` SET `cash`=#Cash,
`distance_driven`=#DistanceDriven, `jobs_done`=#JobsDone,
`job_rank`=#JobRank WHERE `username`='#Username';"
, Connection);
Command.Parameters.AddWithValue("#Cash", Cash);
Command.Parameters.AddWithValue("#DistanceDriven", DistanceDriven);
Command.Parameters.AddWithValue("#JobsDone", JobsDone);
Command.Parameters.AddWithValue("#JobRank", JobRank);
Command.Parameters.AddWithValue("#Username", UName);
int result = Command.ExecuteNonQuery(); // result should be 1
Console.WriteLine(result); // ends up being 0
The connection opens fine, but I have no idea why it won't execute the query with the parameters.
Here is the function that requires this update:
public void UpdateUserInfo(object sender, ElapsedEventArgs evt, string uUName)
{
bool cont = false;
Console.WriteLine("UUI 1: " + evt.SignalTime); // gets here fine
try
{
Console.WriteLine("UUI 2: " + evt.SignalTime); // gets here fine
Database database = new Database();
database.Connect();
if (database.UpdateUserData(uUName, TotalCashWallet, TotalDistanceDriven, JobsDone, JobRank))
{
cont = true;
Console.WriteLine("UUI 3: " + evt.SignalTime); // doesn't get here
}
if (cont == true)
{
cont = false;
Console.WriteLine("UUI 4: " + evt.SignalTime);
if (database.UpdateUserBank(uUName, BankInfo.Money, BankInfo.BonusPercentage, BankInfo.BonusLevel))
{
UserInfoUpdated = true;
Console.WriteLine("UUI 5: " + evt.SignalTime);
UserInfoUpdatedTimer.Enabled = true;
return;
}
}
UserInfoUpdated = false;
return;
}
catch (Exception e)
{
Console.WriteLine("UUI 6: " + evt.SignalTime);
Console.WriteLine(e.Message);
ErrorHandler.WriteToLog(e.StackTrace);
ErrorHandler.WriteToLog(e.Message);
ErrorHandler.WriteToLog("------------------------------");
}
return;
}
It doesn't get to the catch part, so it won't log anything.
I tried with both Exception and MysqlException, but it doesn't catch an error.
Doing it the unsafe way works
MySqlCommand Command = new MySqlCommand("
UPDATE `users`
SET `cash`=" + Cash + ",
`distance_driven`=" + DistanceDriven + ",
`jobs_done`=" + JobsDone + ",
`job_rank`=" + JobRank + "
WHERE `username`='" + UName + "';"
, Connection);
You don't need the single quotes around string parameters. Use this query instead:
string query = #"
UPDATE `users` SET
`cash`=#Cash,
`distance_driven`=#DistanceDriven,
`jobs_done`=#JobsDone,
`job_rank`=#JobRank
WHERE
`username`=#Username"
MySqlCommand command = new MySqlCommand(query, Connection);

Retrieving the return value from Oracle with C#

I'd like to be able to retrieve the return value from a function in Oracle with c#.
Currently, this is what I have:
For SQL:
FUNCTION add_resource (
project_view BOOLEAN,
project_id NUMBER,
worker_id NUMBER,
role_id NUMBER) RETURN NUMBER IS
resource_id NUMBER;
BEGIN
INSERT INTO RESOURCE_T (WORKERID, ROLEID, PROJECTID)
VALUES (worker_id, role_id, project_id)
RETURNING RESOURCEID INTO resource_id;
RETURN resource_id;
END add_resource;
For C#
cmdText = "DECLARE resource_id NUMBER; BEGIN resource_id := PKG_RAP.add_resource(" + projectView + "," + id + "," + record["WORKERID"] + "," + record["ROLEID"] + "); END;";
using (OracleCommand cmd = new OracleCommand(cmdText, conn))
{
OracleTransaction trans = conn.BeginTransaction();
try
{
OracleParameter prm = new OracleParameter("resource_id", OracleDbType.Int32, ParameterDirection.ReturnValue);
cmd.Parameters.Add(prm);
cmd.ExecuteNonQuery();
trans.Commit();
}catch
{
trans.Rollback();
throw;
}
}
The query works individually when I test it out in the database, however, the c# is not able to grab the value for resource_id and only gets "null". Any tips would be appreciated!
Does something like this not work?
cmdText = #"select PKG_RAP.add_resource(:projectView, :projectId, :workerId, :roleId) from dual";
using (var cmd = new OracleCommand(cmdText, conn))
using (cmd.Parameters.Add(":projectView", projectView))
using (cmd.Parameters.Add(":projectId", id))
using (cmd.Parameters.Add(":workerId", record["WORKERID"]))
using (cmd.Parameters.Add(":roleId", record["ROLEID"]))
using (var tx = conn.BeginTransaction()) {
try {
// resource ID
var resourceId = Convert.ToInt32(cmd.ExecuteScalar());
tx.Commit();
return resourceId;
} catch {
tx.Rollback();
throw;
}
}
This seems (to me) like the simplest solution to calling a PL-SQL function to return a single value.
ETA: I don't have sufficient rep to comment, yet, but Marc, above, means that you don't return anything in the PL-SQL block you are executing.
The command text must be like this one if you like to call a function (and if you want or have to avoid select ... from dual:
cmdText = "BEGIN :resource_id := PKG_RAP.add_resource(" + projectView + "," + id + "," + record["WORKERID"] + "," + record["ROLEID"] + "); END;";
As John Pederson already answered, all parameters should be defined as bind values, e.i.
cmdText = "BEGIN :resource_id := PKG_RAP.add_resource(:projectView, :projectId, :workerId, :roleId); END;";
However, I don't think you can use boolean variables when calling from C#. You have to cast it, e.g. to "0" and "1"

C# reading int from mysql

Having problem reading a value from my table in mysql, is the index value i cant read the value back no matter what. all i get is the initialized value of 0 i dont get any error because it return 0, if i run the query in the database it get the correct value. i tried to use executeScalar() but with the same result .
MySqlConnection conn = new MySqlConnection(MyConString);
ulong ukey=0;
try
{
string sql_users2 = "SELECT `key` FROM `permuser` WHERE `user` = '" + myuser + "' AND `code` = '" + mycode + "'";
MySqlCommand cmdSel2 = new MySqlCommand(sql_users2, conn);
conn.Open();
MySqlDataReader dr2 = cmdSel2.ExecuteReader();
dr2.Read();
ukey = dr2.GetUInt64(dr2.GetOrdinal("key"));
// MessageBox.Show("Sorry " + myuser + " already have access to " + mycode + ",\nIf this is an extension, search for the user which key is " + ukey + " and edit the end date.", "Duplicate User Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
dr2.Close();
dr2.Dispose();
}
catch (MySqlException ex) //catch 2
{
MessageBox.Show("catch ukey\nCan't connect to database\n" + ex.ToString());
}
conn.Close();
conn.Dispose();
You are returning a single value from your query, so you could use directly ExecuteScalar instead of ExecuteReader. (the link point to the description for SqlServer, but it is the same for MySql)
An important question to never forget is the usage of parameters instead of string concatenation.
What happen if your myuser or mycode variables contain a single quote? You get wrong results or syntax errors.
Of course, the main problem is the Sql Injection attack to never understimate.
using(MySqlConnection conn = new MySqlConnection(MyConString))
{
ulong ukey=0;
try
{
string sql_users2 = "SELECT `key` FROM `permuser` WHERE `user` = #usr AND `code` = #code";
MySqlCommand cmdSel2 = new MySqlCommand(sql_users2, conn);
conn.Open();
cmdSel2.Parameters.AddWithValue("#usr", myuser);
cmdSel2.Parameters.AddWithValue("#code", mycode);
object result = cmdSel2.ExecuteScalar();
if(result != null)
ukey = Convert.ToUInt64(result);
}
catch (MySqlException ex) //catch 2
{
MessageBox.Show("catch ukey\nCan't connect to database\n" + ex.ToString());
}
}
also I am a bit perplexed about your usage of UInt64. What kind of datatype is stored in the key column?
way is many simply:
ukey = (uint)dr2[0];

Categories

Resources