SQL Query issues: invalid identifier - c#

I've been working on a delete function for a while now, and I cannot get past this error.
Delete Failed ORA-00904 "SYSTEM"."DATA"."DATAROWVIEW": invalid identifier
private void button3_Click(object sender, EventArgs e)
{
string yesNoPrompt = "Are you sure you want to delete this patient?";
const string caption = "";
var result = MessageBox.Show(yesNoPrompt, caption,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
string sql = "DELETE FROM CLIENT WHERE (CLI_LNAME =" + listBox1.SelectedItem.ToString() + ")" ;
try
{
string connectionString = GetConnectionString();
using (OracleConnection connection = new OracleConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
OracleCommand command = new OracleCommand(sql, connection);
command.CommandType = CommandType.Text;
command.ExecuteNonQuery();
}
}
catch (System.Data.OracleClient.OracleException ex)
{
MessageBox.Show("Delete Failed" + ex.Message);
}
}
}
The table in the database is CLIENT and I am trying to find a specific person by their last name, or CLI_LNAME. I don't think the problem is in the name being passed, but more of how it is being passed.
Any ideas?

Your query gets translated to
DELETE FROM CLIENT WHERE (CLI_LNAME = SYSTEM.DATA.DATAROWVIEW)
Due to the missing single quotes and hence its trying to find a column named SYSTEM.DATA.DATAROWVIEW which is not present in the Client table. hence the error.
When you use single quotes then its looking for the text in that particular column
DELETE FROM CLIENT WHERE (CLI_LNAME = 'PatientName') // Now its not a column as such
Use Parameterized queries to avoid SQL injection

Looks like listBox1.SelectedItem.ToString() returns "SYSTEM"."DATA"."DATAROWVIEW". You probably want to access a specific item of the DataRowView that's the SelectedItem, not the entire DataRowView object itself. Maybe listBox1.SelectedItem[0].ToString() is what you want?.
Also you have to add quotes as #Habib.OSU mentions.
And the obligatory sql injection warning: Don't concatenate user inputs into SQL string. It opens up for SQL injection attacks. Use parameterized queries.

you are missing single quote in parameters
string sql = "DELETE FROM CLIENT WHERE (CLI_LNAME ='" + listBox1.SelectedItem.ToString() + "')" ;
Its better if you could use Parameterized query

Related

Check if a row exists using windows form?

I was creating an Appointment Table and i want to check if the row contains same Date,Slot,HR exists before another user enter.
The Connection is Opened Before this shown code.
SqlCommand slot_check = new SqlCommand("select * from Appointment where AppoinmentDate='"+textBox1.Text+"' and Slot='"+comboBox3.Text+ "'and HRName='" +comboBox2.Text+"'");
SqlDataReader Exist = slot_check.ExecuteReader();
if (Exist.HasRows)
{
string message = "Appointment Already Exists!!!!!";
MessageBox.Show(message);
}
else
{
string message = "Update";
MessageBox.Show(message);
}
System.InvalidOperationException: 'ExecuteReader: Connection property has not been initialized.'
To execute a command two informations are essential:
The sql string to execute and the connection to reach the database.
Without the connection your command cannot be executed because the framework doesn't know how to read or write the database.
There is an overload for the SqlCommand constructor that takes the two required parameters:
SqlCommand cmd = new SqlCommand(sqlText, connectionInstance);
So your code should be something like this
// The command text to run, without string concatenations and with parameters placeholders
string sqlText = #"select * from Appointment
where AppoinmentDate=#aptDate
and Slot=#slot
and HRName=#name";
// Using statement to correctly close and dispose the disposable objects
using(SqlConnection cnn = new SqlConnection(connectionString))
using(SqlCommand slot_check = new SqlCommand(sqlText, cnn))
{
// A parameter for each placeholder with the proper datatype
cmd.Parameters.Add("#aptDate", SqlDbType.Date).Value = Convert.ToDateTime(textBox1.Text);
cmd.Parameters.Add("#slot", SqlDbType.NVarChar).Value = comboBox3.Text;
cmd.Parameters.Add("#name", SqlDbType.NVarChar).Value = comboBox2.Text;
cnn.Open();
// Even the SqlDataReader is a disposable object
using(SqlDataReader Exist = slot_check.ExecuteReader())
{
if (Exist.HasRows)
{
string message = "Appointment Already Exists!!!!!";
MessageBox.Show(message + " " + Exist + comboBox2.Text);
}
else
{
string message = "Update";
MessageBox.Show(message);
}
}
}
As you can see the code now has a connection passed to the command constructor and a command text built without concatenating strings but using parameters.
Using parameters is a mandatory approach for any kind of database related operation. Without parameters your code could be exploited with the well known Sql Injection hack, but also, the simple presence of a single quote in your values, could break the sql syntax resulting in a Syntax Error Exception
Note that this code could still be wrong because I don't know what kind of data is stored in your table in the columns used in the WHERE statement. I assumed some kind of type but you should check against your table and verify if they are correct.

Row Deletion ADO.Net, ASP.Net

I am trying to work with a contact list and want to remove all of the info on a person when I type in their name. I am using a sql table -named Contact- that contains the Name, Email and Address of a contact. I have the following code:
protected void Delete_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnect"].ConnectionString);
con.Open();
string delete = "DELETE FROM Contact WHERE Name =" + NameToDelete.Text;
SqlCommand cmd = new SqlCommand(delete, con);
try
{
cmd.Parameters.AddWithValue("#Name", delete);
cmd.ExecuteNonQuery();
Response.Redirect("ViewContacts.aspx");
}
catch(Exception ex)
{
Response.Write(ex);
}
}
When I use this, it seems to be comparing the column Name to the name I am putting in. So the name Bill is being compared against the column header Name instead of what is in the name.
You need to use single quotes around the values with var(char) types. If you don't use quotes it will think that you are referencing a column name instead of value.
It's valid for all databases, following is from oracle docs:
character literals are enclosed in single quotation marks, which
enable Oracle to distinguish them from schema object names.
https://docs.oracle.com/cd/A87860_01/doc/server.817/a85397/sql_elem.htm
string delete = "DELETE FROM Contact WHERE Name ='" + NameToDelete.Text + "'";
Actually what you are trying to do is using sqlcommand parameter, then you need to use parameter name using #[ParameterName] in sql statement.
string delete = "DELETE FROM Contact WHERE Name = #Name";
Seems that your problem is that you are using the variable delete in two instances. First for create the command that is fine and second as the parameter value, which is wrong. In the parameter value probably you must use the value tthat you want to delete.
You have several serious problems with your code.
Your connection is never closed or disposed. Use Using blocks which will close and dispose of database objects even if there is an error.
You are concatenating a string to get your Sql statement risking Sql injection and damage to your database.
You are adding a parameter to your command when there are no parameters in your Sql statement.
You are using .AddWithValue which takes the parameter name and the parameter value as arguments. You have provided your entire Sql statement as the value of #Name. This should be NameToDelete.Text.
Do not use .AddWithValue. Use .Add(parameter Name, Sql data type).Value = value of parameter. This can speed up queries and avoids type mismatches in the database.
If name is your Primary Key, you are OK, but if not you should delete by the primary key or send all values in the Where clause.
protected void Delete_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbconnect"].ConnectionString))
{
string delete = "DELETE FROM Contact WHERE Name = #Name;"; //no single quotes to worry about
using (SqlCommand cmd = new SqlCommand(delete, con))
{
cmd.Parameters.Add("#Name", SqlDbType.VarChar).Value = NameToDelete.Text; //just guessed at the VarChar - check your database for type
try
{
con.Open();
cmd.ExecuteNonQuery();
Response.Redirect("ViewContacts.aspx");
}
catch (Exception ex)
{
Response.Write(ex.Message); //ex by itself, will get you nothing but the fully qualified name of Exception
}
}
}
}

I need some advice with mysql

Hello I am trying to do an application in C# very simple it has a search bar(textbox) and a button, my purpose is for eg when I type E1 I want to display the item from MySql. At the moment, when I type E1 I get some kind of error that says unknown column "e1". I will post my code below:
public partial class MainWindow : Window
{
MySqlConnection connection = new MySqlConnection("datasource=localhost;port=3306;username=root;password=pass;");
MySqlCommand cmd;
MySqlDataReader mdr;
private void button_Click(object sender, RoutedEventArgs e)
{
try
{
connection.Open();
string selectRaspuns = "SELECT * FROM testdb.element WHERE name="+ userInput.Text;
cmd = new MySqlCommand(selectQuery, connection);
mdr = cmd.ExecuteReader();
if (mdr.Read())
{
r1.GetDenumire(mdr.GetString("name"));
r1.GetInformatii(mdr.GetString("info"));
r1.Show();
}
else
{
MessageBox.Show("Error");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
connection.Close();
}
}
}
I want for eg when I type E1 to display from my mySql db information's about E1 that is stored in table element column name and info can you point me what am i doing wrong ?Thanks
The problem is in this line of code:
string selectRaspuns = "SELECT * FROM testdb.element WHERE name="+ userInput.Text;
When you concatenate your input of "E1", the result is:
SELECT * FROM testdb.element WHERE name=E1
Since your string is not quoted, MySql interprets it as a column name, thus you get the "invalid column name" error.
At the very minimum, you must add quotes, like so:
string selectRaspuns = "SELECT * FROM testdb.element WHERE name='" + userInput.Text + "'";
By doing this, your resulting SQL is:
SELECT * FROM testdb.element WHERE name='E1'
and MySql will interpret "E1" as a string, which is what you intend.
That said, creating SQL using string concatenation is a bad practice and can lead to SQL injection vulnerabilities. Once you have it working as desired, I strongly urge you to circle back and replace the string concatenation with parameterized queries.

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

error in query in asp.net [duplicate]

This question already has answers here:
SQL Server Invalid column name when adding string value
(5 answers)
Closed 6 years ago.
Error is showing that invalid column name mustufain.
mustufain is the value of UserName.Text.toString()
string query = "select userid from register where username = " + UserName.Text.ToString() + " and " + "password = " + Password.Text.ToString();
SqlCommand cmd1 = new SqlCommand(query,connection);
connection.Open();
SqlDataReader rd1 = cmd1.ExecuteReader();
while(rd1.Read())
{
Session["checkuserid"] = rd1["userid"];
}
connection.Close();
Firstly, you should not be using string concatenation to build your queries as it can leave you vulnerable to things like SQL Injection attacks and it can cause issues with your queries being incorrect (as you are missing tick marks around your parameters) :
// This would attempt to state username = mustufain instead of
// username = 'mustufain' (and SQL doesn't know what mustufain is)
var query = "select userid from register where username = '" + UserName.Text + "' and " + "password = '" + Password.Text + "'";
A better approach using parameterization would look like the following, which avoids the incorrect syntax and offers you protection against any nasty injections :
// Open your connection
using(var connection = new SqlConnection("{your connection string}"))
{
// Build your query
var query = "SELECT TOP 1 userid FROM register WHERE username = #username AND password = #password";
// Build a command (to execute your query)
using(var command = new SqlCommand(query, connection))
{
// Open your connection
connection.Open();
// Add your parameters
command.Parameters.AddWithValue("#username",UserName.Text);
command.Parameters.AddWithValue("#password",Password.Text);
// Execute your query
var user = Convert.ToString(command.ExecuteScalar());
// If a user was found, then set it
if(!String.IsNullOrEmpty(user))
{
Session["checkuserid"] = user;
}
else
{
// No user was found, consider alerting the user
}
}
}
Finally, you may want to reconsider how you are storing your credentials (in clear text). ASP.NET offers a wide variety of providers that can help handle this process for you so that you don't have to do it yourself.
You are trying to concatenate strings to build an sql query and, as usual, you get errors. In your specific case you forget to enclose your string values between single quotes. But the only correct way to do this query is by the way of a parameterized query
string query = #"select userid from register
where username = #name and password = #pwd";
using(SqlCommand cmd1 = new SqlCommand(query,connection))
{
connection.Open();
cmd1.Parameters.Add("#name", SqlDbType.NVarChar).Value = UserName.Text;
cmd1.Parameters.Add("#pwd", SqlDbType.NVarChar).Value = Password.Text;
using(SqlDataReader rd1 = cmd1.ExecuteReader())
{
....
}
}
Notice also that storing passwords in clear text in your database is a very bad practice and a strong security risk. On this site there are numerous questions and answers that explain how to create an hash of your password and store that hash instead of the clear text
For example: Best way to store passwords in a database

Categories