Problem with Syntax Error in SQL statement - c#

I am trying to get a specific single value from an Access Database using C#.
For some reason what I am asking for is giving me an exception of
Syntax error in FROM clause
and I cant work out why.
I have tried running the SQL directly in Access itself and it works fine and gives me back the results I want, but I have no idea why its not working in my program.
ProbID is a number field as far as Access describes it and CorrDetails is a memo field.
For simplicity i have set the SQL to look for a specific value (137) but once i have the code working i will make it paramiterised.
Any ideas?
string corrAct;
OleDbConnection dbConnection;
dbConnection = new OleDbConnection(vDbString);
string sqlString = "SELECT CorrDetails FROM Action WHERE ProbID=137";
OleDbCommand command = new OleDbCommand(sqlString, dbConnection);
using (dbConnection)
{
MessageBox.Show(sqlString);
dbConnection.Open();
corrAct = (String)command.ExecuteScalar();
rtfCorrectiveAction.Text = Convert.ToString(corrAct);
dbConnection.Close();
}

Action is a reserved word in MS Access.
Wrap it with []:
string sqlString = "SELECT CorrDetails FROM [Action] WHERE ProbID=137";

The problem is you havent taken into account keywords in SQL. https://learn.microsoft.com/en-us/sql/odbc/reference/appendixes/reserved-keywords?view=sql-server-ver15
Action is a keyword so should not be used really in another context, to use them put [] round them some it becomes
select stuff from [Action] where stuff=true

Related

Database problem in visual studio (c# and SQL Server)

I am writing a Windows Forms app in which I have to simulate keeping count of who is missing in class. I have made a database inside Visual Studio which works well. I also found a tutorial on youtube on how to do it, so I did it. In one part of the video he puts an "#(Name of the variable in the table)" instead of a value in query. For him it works, for me it doesn't and i don't know why. Please help.
private void napuniUcenici()
{
string query = "SELECT a.Ime FROM Ucenici a " +
"INNER JOIN RazrediUcenici b ON a.Id = b.UcenikId " +
"WHERE b.RazredId = #RazredId";
using (connection = new SqlConnection(connectionString))
using (SqlCommand command = new SqlCommand(query, connection))
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
{
command.Parameters.AddWithValue("#RazredId", lstUcenici.SelectedValue);
DataTable uceniciTable = new DataTable();
adapter.Fill(uceniciTable);
lstUcenici.DisplayMember = "Ime";
lstUcenici.ValueMember = "Id";
lstUcenici.DataSource = uceniciTable;
}
}
This happens when I call this function in my code. And it returns this massage:
System.Data.SqlClient.SqlException:
'The parameterized query
'(#RazredId nvarchar(4000))SELECT a.Ime FROM Ucenici a INNER JOIN'
expects the parameter '#RazredId', which was not supplied.'
Also, RazredId isn't a navchar(4000), it is a regular integer. The guy in the video didn't have this problem.
The video: https://www.youtube.com/watch?v=_PCBTiXL884
[1
[2
[3
try to pass an explicit value instead:
command.Parameters.AddWithValue("#RazredId", 1);
and see whats's happen. It is correct to retain the # in the param name, unlike as previous repolies.
Ok guys, so... I am dumb xD
What i did wrong is that the second parameter in this line was wrong(the lstRazredi was previously lstUcenici which is the wrong table)
command.Parameters.AddWithValue("#RazredId", lstRazredi.SelectedValue);
So i changed that and now i works perfectly.
Sorry for bothering.
Maybe you need to add the parameter before you pass the command to the adapter?

C# Select Query Failed with no errors

I'm having trouble with a simple SELECT query, I cannot see why it isn't working.
Here is the code:
conn.Open();
string GetPayrollQuery = "SELECT PayrollNo FROM [Employee] WHERE (FirstName + ' ' + LastName) = #Name";
OleDbCommand GetPayroll = new OleDbCommand(GetPayrollQuery, conn);
GetPayroll.Parameters.AddWithValue("#Name", OleDbType.VarChar).Value = cbbEmployees.Text;
var GotPayroll = GetPayroll.ExecuteNonQuery();
MessageBox.Show(GotPayroll.ToString());
return Convert.ToInt32(GotPayroll);
The code runs fine however it isn't extracting the data. Can anyone see why this would be?
I bet #name is coming as "MikeSmith" instead of "Mike Smith".
3 things:
try to open SQL profiler and check what you are executing on database
check database collation, is it case sensitive?
remove executenonquery (it's must used with update, delete, not select) and try executescalar (if one result for one row is exptected, otherwise try to fill a datatable or use datareader)
Make sure the same query runs in SQL using those parameter values.
Change GetPayroll.ExecuteNonQuery() to GetPayroll.ExecuteScalar() so to return a single result.
Change GetPayroll.Parameters.AddWithValue("#Name", OleDbType.VarChar).Value = cbbEmployees.Text; to GetPayroll.Parameters.AddWithValue("#Name", cbbEmployees.Text);
Use cbbEmployees.SelectedText. Fixes the problem.

Creating Registration form in c# with mysql

Hello so i m creating a registration form in C# with MySql so it connects to the database and everything but i get this error Napaka pri registraciji Unknown column " in 'field list' the translation of Napaka pri registraciji means Error at registering i just have it in my language. I get this error when i insert data in textboxes and press Register..
the code:
private void btn_Reg_Click(object sender, EventArgs e)
{
MySqlConnection dataConnection = new MySqlConnection();
dataConnection.ConnectionString = "datasource=localhost;port=3306;username=root;password=";
dataConnection.Open();
MySqlTransaction transakcija = dataConnection.BeginTransaction();
MySqlCommand dataCommand = new MySqlCommand();
dataCommand.Connection = dataConnection;
dataCommand.Transaction = transakcija;
try
{
dataCommand.CommandText = "Insert INTO lr.users (upIme,geslo) VALUES (`"+this.tB_upIme.Text+"`,`"+this.tB_geslo.Text+"`)";
dataCommand.CommandType = CommandType.Text;
dataCommand.ExecuteNonQuery();
transakcija.Commit();
MessageBox.Show("Registracija uspešna!");
}
catch (Exception eks)
{
transakcija.Rollback();
MessageBox.Show("Napaka pri registraciji\n" + eks.Message);
}
finally
{
dataCommand.Connection.Close();
}
}
There are two things I immediately see wrong here...
First, you're using back ticks to wrap your values. In MySQL Back ticks represent database objects, so the query is looking for objects named by those values instead of using the values themselves. So instead of this:
`"+this.tB_upIme.Text+"`
You'd want this:
'"+this.tB_upIme.Text+"'
Second, and vastly more importantly, your code is wide open to SQL injection attacks. You'll want to use query parameters, not direct string concatenation. While it may look like you're just putting values into the query string, you're actually taking user input and treating it as executable code in your query string, which means users can run any arbitrary code they want on your database.
First, add parameters to your query:
"Insert INTO lr.users (upIme,geslo) VALUES (#upIme, #geslo)"
(You'll notice this also makes the query a heck of a lot cleaner and easier to read.) Then add your parameters to the command:
dataCommand.Parameters.AddWithValue("#upIme", this.tB_upIme.Text);
dataCommand.Parameters.AddWithValue("#geslo", this.tB_geslo.Text);
Then when you execute that command it will treat the user-input values as values instead of as executable code.
Change to single quotes ' in the values.
dataCommand.CommandText =
"Insert INTO lr.users (upIme,geslo)
VALUES ('"+this.tB_upIme.Text+"','"+this.tB_geslo.Text+"');";

MySQL truncate command with parameter not working

Why do I get an exception when trying to truncate a MySQL table (using MySQL Connector/Net)? I am trying to give the table name with a parameter.
This is the code I'm executing:
var connectionString = "Server="+_server+";Uid="+_user+";Pwd="+_password+";Database="+_database+";";
try
{
using (var conn = new MySqlConnection(connectionString))
{
conn.Open();
const string sql = "TRUNCATE TABLE #tablename"; // also tried with TRUNCATE #tablename
var cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#tablename", "test");
cmd.ExecuteNonQuery();
conn.Close();
}
}
catch (MySqlException ex)
{
Console.WriteLine(ex.ToString());
}
And this is the execption:
MySql.Data.MySqlClient.MySqlException (0x80004005): You have an error
in your SQ L syntax; check the manual that corresponds to your MySQL
server version for the right syntax to use near ''test'' at line 1
When I try a select query, for example, then I don't have any problems. This runs fine and returns correct data:
conn.Open();
const string sql = "SELECT body FROM test WHERE id=#pid";
var cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#pid", 1);
cmd.ExecuteScalar();
conn.Close();
Parameters are used for query values, not object names like tables.
So this will not work for sure.
You need to set the table name in the command string by using string concatenation. You can avoid sql injection attacks by manually checking for weird characters in the table name (spaces, dashes, semicolons, etc..)
I've been playing around with this for a while now, and i can't seem to get it to work either. I can't find any documentation online, so i'm starting to think you may not be able to truncate with a parameter like you've tried.
However, is there really a need to prevent SQL injection on this command? Does the user enter the name of the table they want to truncate, and if so, they're just going to truncate a table which...is essentially what the command does anyway?

MySqlCommand Command.Parameters.Add is obsolete

I'm making an C# windows Form Application in visual studio 2010.
That application is connecting to an mysql database, and I want to insert data in it.
Now do I have this part of code:
MySqlConnection connection;
string cs = #"server=server ip;userid=username;password=userpass;database=databse";
connection = new MySqlConnection(cs);
connection.Open();
MySqlCommand command = new MySqlCommand();
string SQL = "INSERT INTO `twMCUserDB` (`mc_userName`, `mc_userPass`, `tw_userName`, `tw_userPass`) VALUES ('#mcUserName', '#mcUserPass', '#twUserName', '#twUserPass')";
command.CommandText = SQL;
command.Parameters.Add("#mcUserName", mcUserNameNew);
command.Parameters.Add("#mcUserPass", mcUserPassNew);
command.Parameters.Add("#twUserName", twUserNameNew);
command.Parameters.Add("#twUserPass", twUserPassNew);
command.Connection = connection;
command.ExecuteNonQuery();
connection.Close();
The connection is fine. That works.
I readed here that the way that I have now, is an save way to do query's. Is that still right?
And now to the real question. With that code above, I get the following warning in visual studio:
'MySql.Data.MySqlClient.MySqlParameterCollection.Add(string, object)' is obsolete: '"Add(String parameterName, Object value) has been deprecated. Use AddWithValue(String parameterName, Object value)"'
That warning is for every parameters.add
And it isn't even working, because the values that are inserted are #mcUserName, #mcUserPass and so on, instead of the values that the variables mcUserNameNew and so on are holding...
So my question is, am I doing something wrong, and what is the new way to sql injection save do an query?
try AddWithValue
command.Parameters.AddWithValue("#mcUserName", mcUserNameNew);
command.Parameters.AddWithValue("#mcUserPass", mcUserPassNew);
command.Parameters.AddWithValue("#twUserName", twUserNameNew);
command.Parameters.AddWithValue("#twUserPass", twUserPassNew);
and don't wrap the placeholders with single quotes.
string SQL = "INSERT INTO `twMCUserDB` (`mc_userName`, `mc_userPass`, `tw_userName`, `tw_userPass`) VALUES (#mcUserName, #mcUserPass, #twUserName, #twUserPass)";
Edit:
As Bradley Grainger pointed out, in MySQL is safe to use AddWithValue.
I'm keeping my answer if you get here by chance and use Microsoft SQL.
Please read this article, advising you against using AddWithValue:
https://blogs.msmvps.com/jcoehoorn/blog/2014/05/12/can-we-stop-using-addwithvalue-already/
It says basically that AddWithValue could sometimes incorrectly infer the correct type. Use Add instead.
Just edit/remove some code in this part
('#mcUserName', '#mcUserPass', '#twUserName', '#twUserPass')
to
(#mcUserName, #mcUserPass, #twUserName, #twUserPass)
and Add( to AddWithValue(
#mcUserName has to match the mc_userName in the query ..
so your parm should be #mc_userName
This is VB code...
cmd.Parameters.AddWithValue("#number", 1) 'set #number as numeric
cmd.Parameters.AddWithValue("#text", "this will be a text variable")
cmd.Parameters("#number").Value = 321 'now #number has a value
cmd.Parameters("#text").Value = "A string value" 'now #text has a value
cmd.ExecuteNonQuery()
should be used as such to prevent any errors set the dbtype correctly then assign
cmd.Parameters.Add("#ID", MySqlDbType.Int32);
correct way to set a MySqlDBType
cmd.Parameters["#ID"].Value = 1;
now set the value

Categories