Why is this SQL statement giving me an invalid column name error? - sql

I'm trying to use an SQL select statement to read from a database to validate a login form. The problem I'm having is its telling me its an invalid column name.
SELECT * FROM users
WHERE [username] = #theusername
AND [password] = #thepassword
where #theusername is a parameratized value of "Rymo_18", and the password is, for the sake of argument, "password".
The errors I get are:
Invalid column name 'Rymo_18'.
Invalid column name 'password'
Don't know why I'm getting those errors. I've tried swapping the values around the = sign, tried using values directly (username = "Rymo_18") and all other matters of fiddling to fix it, and I've had no luck. There are no other tables called 'user' within my Database.
EDIT: Here's the code as it appears in the C# I'm using:
string user = unametext.Text;
string pword = pwordtext.Text;
string connectionstring = WebConfigurationManager.ConnectionStrings["elmtreeconnect"].ConnectionString;
SqlConnection myconnection = new SqlConnection(connectionstring);
myconnection.Open();
string query = "SELECT * FROM users WHERE (username= #theusername OR email = #theusername) AND password = #thepassword";
SqlCommand attemptLogin = new SqlCommand(query, myconnection);
attemptLogin.Parameters.AddWithValue("#theusername", user);
attemptLogin.Parameters.AddWithValue("#thepassword", pword);
SqlDataReader rdr = attemptLogin.ExecuteReader();
if (rdr.HasRows)
{
Session["user"] = rdr["username"].ToString();
Session["id"] = rdr["id"].ToString();
Session["type"] = rdr["accountType"].ToString();
Response.Redirect("loginsuccess.aspx");
}
else
{
unametext.Text = "";
pwordtext.Text = "";
statusLabel.Text = "Login failed. Please try again, or contact info#elmtree.co.uk for assistance";
}
Thanks for the help!

string query = "select 1 from users where username=#theusername and password=#password";
...
if(rdr.Read()){
...
}
exists should be used in if exists(select...)

Related

ASP.NET and SQL Server : update last record with dynamic values

I'm retrieving an HTTP response which I am deserializing the values into an Azure SQL database. I cannot find any way to format the SQL command to UPDATE string variables into the last record of the table. The intent is to overwrite the last record with each new token to avoid database maintenance requirements. I can statically write a value as in the example below, but I need it to be dynamically passed by variable which seems to throw off the syntax or command execution for some reason. No errors or exceptions are thrown - it just doesn't do anything.
Does anyone have any ideas on how I could go about accomplishing this? The SQL specific code is listed below for reference.
dynamic access = JsonConvert.DeserializeObject(response.Content);
string accessToken = access.access_token;
string timestamp = centralTime.ToString();
System.Data.SqlClient.SqlConnection connect = new System.Data.SqlClient.SqlConnection(connectionString);
System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand();
command.CommandType = System.Data.CommandType.Text;
// this works as needed to insert a new record where required, but builds record counts over time
// command.CommandText = #"INSERT INTO AccessTokens (Token, LastRefreshDate) VALUES (#Token, #LastRefreshDate)";
// command.Parameters.AddWithValue("#Token", accessToken);
// command.Parameters.AddWithValue("#LastRefreshDate", centralTime);
// I've tried as many variations as possible based on what's available online upon searching; these are two examples that don't work
// command.CommandText = #"UPDATE TOP 1 * FROM AccessTokens (Token, LastRefreshDate) VALUES (#Token, #LastRefreshDate)";
// command.CommandText = #"UPDATE AccessTokens SET Token = " + accessToken + " , LastRefreshDate = " + timestamp;
// this will update the record with the new value, but it's static
command.CommandText = #"UPDATE AccessTokens SET Token = 12345";
string test = "test";
// attempting to update with a string variable does not work, which is the desired outcome in order to maintain only one record with a dynamically changing value over time
// command.CommandText = #"UPDATE AccessTokens SET Token = " + test;
command.Connection = connect;
connect.Open();
command.ExecuteNonQuery();
connect.Close();
The understanding is that you need to continually update the last token inserted into your AccessToken table. Assuming your LastRefreshDate is unique enough into the milliseconds, this should look like
command.CommandText = #"UPDATE AccessTokens set Token = #Token where LastRefreshDate = (select Max(LastRefreshDate) from AccessTokens)"
Ideally, if this token exists with a bunch of other access tokens you would have a unique ID in that AccessToken where it's restricted to a particular id like:
command.CommandText = #"UPDATE AccessTokens set Token = #Token where LastRefreshDate = (select Max(LastRefreshDate) from AccessTokens and ID=#ID) and ID=#ID"

Login Comparing hash value in a database

I am attempting to make a simple sign on portion of an app I am creating. To confirm sign in, I am just attempting to make sure that the hash value of the password entered, matches that which is stored in my local database: App_Users ) '
ButtonClick:
string AppUsername = textBox2.Text.ToString();
string AppPassword = textBox1.Text.ToString();
//- Hashed-V-
byte[] salt;
new RNGCryptoServiceProvider().GetBytes(salt = new byte[16]);
var pbkdf2 = new Rfc2898DeriveBytes(AppPassword, salt, 10000);
byte[] hash = pbkdf2.GetBytes(20);
byte[] hashBytes = new byte[36];
Array.Copy(salt, 0, hashBytes, 0, 16);
Array.Copy(hash, 0, hashBytes, 16, 20);
string savedPasswordHash = Convert.ToBase64String(hashBytes); // <-- see ' https://stackoverflow.com/questions/4181198/how-to-hash-a-password ' for the part on comparing the recalculated
//-
SqlConnection con = new SqlConnection();
con.ConnectionString = ("Data Source=DESKTOP-PGHMM6M;Initial Catalog=LocalUsers;Integrated Security=True");
con.Open();
var cmd = new SqlCommand(#"SELECT Username, Hash FROM App_Users WHERE (Hash = #Hash");
cmd.Connection = con;
savedPasswordHash = cmd.ExecuteScalar() as string;
if (cmd.ExecuteNonQuery() > 0) {
MessageBox.Show(" Query successful..something matched.. ");
//change page.. load a profile?
}
However, I am getting the error:
'Must declare the scalar variable "#Hash".'
I've searched around but I'm not sure what the next step for exactly what I am trying to do is.. Sorry this is probably a bad question, sql-wise. I think it has something to do with an adapter?
You didn't pass a value for the #Hash parameter in the query. And you should also check for the user name in the query or else the login attempt is successful if any login uses the given password.
Try something like:
...
var cmd = new SqlCommand(#"SELECT Username, Hash FROM App_Users WHERE Hash = #Hash AND Username = #Username");
cmd.Connection = con;
cmd.Parameters.Add("#Hash", SqlDbType.VarChar, 48).Value = savedPasswordHash;
cmd.Parameters.Add("#Username", SqlDbType.NVarChar, 32).Value = AppUsername;
if (cmd.ExecuteNonQuery() > 0) {
...
This assumes, that App_Users.Hash is a VARCHAR(48) and App_Users an NVARCHAR(32). You may need to change it to match the data types you're actually using.

Like and = operater is not working together in signal query

I am using sap.net web form. In this web form i have a text and a button. user enter name or id and hit search button. Searching with id is working fine but with name it is not working.
What i am missing here help me out please.
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
try
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR DriverID = #search) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("#search", SearchTextBox.Text);
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
catch (SqlException exe)
{
throw exe;
}
}
}
The code is generating an exception. The fact that you're unaware of this indicates that you have "error handling" somewhere in your system that is, in fact "error hiding". Remove empty catch blocks, or pointless catch blocks such as the one in your question that just destroys some information in the exception and re-throws it. Those aren't helping you.
The actual problem is that the DriverID column is int and your parameter is varchar. So long as the varchar contains a string that can be converted to a number (which is the direction that the conversion happens in due to precedence), the query is well-formed.
As soon as the parameter contains a string that cannot be implicitly converted to a number, SQL Server generates an error that .NET turns into an exception.
For your LIKE variant, you're forcing a conversion in the opposite direction (numeric -> varchar) since LIKE only operates on strings. That conversion will always succeed, but it means that you're performing textual comparisons rather than numeric, and also means there's no possible index usage here.
I'd suggest that you change your C# code to attempt a int.TryParse on the input text and then uses two separate parameters to pass strings and (optionally) their numeric equivalent to SQL Server. Then use the appropriate parameters in your query for each comparison.
Something like:
String Status = "Active";
String BDstring = ConfigurationManager.ConnectionStrings["CS"].ConnectionString;
using (SqlConnection conn = new SqlConnection(BDstring))
{
String query = "SELECT * from Driver where(Name LIKE '%' + #search + '%' OR " +
"DriverID = #driverId) AND Status = 'Active'";
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.Add("#search", SqlDbType.VarChar,50).Value = SearchTextBox.Text;
cmd.Parameters.Add("#driverId", SqlDbType.Int);
int driverId;
if(int.TryParse(SearchTextBox.Text, out driverId))
{
cmd.Parameters["#driverId"].Value = driverId;
}
conn.Open();
SqlDataReader SDR = cmd.ExecuteReader();
DataTable DT = new DataTable();
if (SDR.HasRows)
{
DT.Load(SDR);
GridView.DataSource = DT;
GridView.DataBind();
}
}
"SELECT * from Driver where (Name LIKE '%" + #search + "%'
OR DriverID = '" + #search + "' ) AND Status = 'Active'";
how about this?

Invalid column name when performing update

I have been trying to update data to database however i met this problem.I tried deleting the table and creating a new table yet the problem still persist.Below are the codes.Any help will be greatly appreciated
public int UpdateNOK(string wardClass, DateTime admissionDT, string nokFName, string nokLName, string nokNRIC, DateTime nokDOB, string nokGender, string nokNationality, string nokRelationship, int nokContactH, int nokContactHP, string nokEmail, string nokAddr1, string nokAddr2, string nokState, int nokZIP, string nokCountry, DateTime dischargeDT, string patientNRIC)
{
StringBuilder sqlStr = new StringBuilder();
int result = 0;
SqlCommand sqlCmd = new SqlCommand();
sqlStr.AppendLine("Update patientAdmission");
sqlStr.AppendLine("SET wardClass = #parawardClass,admissionDT = #paraadmissonDT, nokFName = #parapatientNokFname, nokLName = #parapatientNokLname,nokNRIC = #parapatientNokNRIC, nokDOB = #parapatientNOKDOB, nokGender = #parapatientNokGender, nokNationality = #parapatientNokNationality,");
sqlStr.AppendLine("nokRelationship = #parapatientNokRelationship,nokContactH = #parapatientNokContactH,nokContactHP = #parapatientNokContactHP, nokEmail = #parapatientNokEmail, nokAddr1 = #parapatientNokAddr1,nokAddr2 = #parapatientNokAddr2,nokState = #parapatientNokState, nokZIP = #parapatientNokZIP,");
sqlStr.AppendLine("nokCountry = #parapatientNokCountry, dischargeDT = #paradischargeDateTime");
sqlStr.AppendLine("WHERE patientNRIC = #parapatientNRIC");
try
{
SqlConnection myConn = new SqlConnection(DBConnect);
sqlCmd = new SqlCommand(sqlStr.ToString(), myConn);
sqlCmd.Parameters.AddWithValue("#parawardClass", wardClass);
sqlCmd.Parameters.AddWithValue("#paraadmissonDT", admissionDT);
sqlCmd.Parameters.AddWithValue("#parapatientNokFname", nokFName);
sqlCmd.Parameters.AddWithValue("#parapatientNokLname", nokLName);
sqlCmd.Parameters.AddWithValue("#parapatientNokNRIC", nokNRIC);
sqlCmd.Parameters.AddWithValue("#parapatientNOKDOB", nokDOB);
sqlCmd.Parameters.AddWithValue("#parapatientNokGender", nokGender);
sqlCmd.Parameters.AddWithValue("#parapatientNokNationality", nokNationality);
sqlCmd.Parameters.AddWithValue("#parapatientNokRelationship", nokRelationship);
sqlCmd.Parameters.AddWithValue("#parapatientNokContactH", nokContactH);
sqlCmd.Parameters.AddWithValue("#parapatientNokContactHP", nokContactHP);
sqlCmd.Parameters.AddWithValue("#parapatientNokEmail", nokEmail);
sqlCmd.Parameters.AddWithValue("#parapatientNokAddr1", nokAddr1);
sqlCmd.Parameters.AddWithValue("#parapatientNokAddr2", nokAddr2);
sqlCmd.Parameters.AddWithValue("#parapatientNokState", nokState);
sqlCmd.Parameters.AddWithValue("#parapatientNokZIP", nokZIP);
sqlCmd.Parameters.AddWithValue("#parapatientNokCountry", nokCountry);
sqlCmd.Parameters.AddWithValue("#paradischargeDateTime", dischargeDT);
sqlCmd.Parameters.AddWithValue("#parapatientNRIC", patientNRIC);
myConn.Open();
result = sqlCmd.ExecuteNonQuery();
myConn.Close();
Console.WriteLine(result);
}
catch (Exception ex)
{
logManager log = new logManager();
log.addLog("patientNOKDAO.UpdateNOK", sqlStr.ToString(), ex);
}
return result;
}
}
You should check table definition (sp_help) against your used columns in the table patientAdmission:
wardClass
admissionDT
nokFName
nokLName
nokNRIC
nokDOB
nokGender
nokNationality
nokRelationship
nokContactH
nokContactHP
nokEmail
nokAddr1
nokAddr2
nokState
nokZIP
nokCountry
dischargeDT
patientNRIC
If database default collation is a case-sensitive one, column names above must be exactly as defined in the table (case cannot be different).
One way to find the problem faster is to run SQL profiler and see the exact query against the database. Copy-paste it from there and run it into an Management Studio (SSMS) query file (use BEGIN TRAN .. ROLLBACK to ensure that nothing will actually be changed when you make it work). SSMS will try to indicate the exact column with the problem when clicking on the error.

Oracle Parameters in .net sql queries - ORA-00933: SQL command not properly ended

I am trying to do create a where clause to pass as a parameter to an Oracle command and it's proving to be more difficult than I thought. What I want to do is create a big where query based off user input from our application. That where query is to be the single parameter for the statement and will have multiple AND, OR conditions in it. This code here works however isn't exactly what I require:
string conStr = "User Id=testschema;Password=pass12341;Data Source=orapdex01";
Console.WriteLine("About to connect to Database with Connection String: " + conStr);
OracleConnection con = new OracleConnection(conStr);
con.Open();
Console.WriteLine("Connected to the Database..." + Environment.NewLine + "Press enter to continue");
Console.ReadLine();
// Assume the connection is correct because it works already without the parameterization
String block = "SELECT * FROM TEMP_VIEW WHERE NAME = :1";
// set command to create anonymous PL/SQL block
OracleCommand cmd = new OracleCommand();
cmd.CommandText = block;
cmd.Connection = con;
// since execurting anonymous pl/sql blcok, setting the command type
// as text instead of stored procedure
cmd.CommandType = CommandType.Text;
// Setting Oracle Parameter
// Bind the parameter as OracleDBType.Varchar2
OracleParameter param = cmd.Parameters.Add("whereTxt", OracleDbType.Varchar2);
param.Direction = ParameterDirection.Input;
param.Value = "MY VALUE";
// Get returned values from select statement
OracleDataReader dr = cmd.ExecuteReader();
// Read the identifier for each result and display it
while (dr.Read())
{
Console.WriteLine(dr.GetValue(0));
}
Console.WriteLine("Selected successfully !");
Console.WriteLine("");
Console.WriteLine("***********************************************************");
Console.ReadKey();
If I change the lines below to be the type of result I want then I get an error "ORA-00933: SQL command not properly ended":
String block = "SELECT * FROM TEMP_VIEW :1";
...
...
param.Value = "WHERE NAME = 'MY VALUE' AND ID = 5929";
My question is how do I accomplish adding my big where query dynamically without causing this error?
Sadly there is no easy way to achieve this.
One thing you will need to understand with parameterised SQL in general is that bind parameters can only be used for values, such as strings, numbers or dates. You cannot put bits of SQL in them, such as column names or WHERE clauses.
Once the database has the SQL text, it will attempt to parse it and figure out whether it is valid, and it will do this without taking any look at the bind parameter values. It won't be able to execute the SQL without all of the values.
The SQL string SELECT * FROM TEMP_VIEW :1 can never be valid, as Oracle isn't expecting a value to immediately follow FROM TEMP_VIEW.
You will need to build up your SQL as a string and also build up the list of bind parameters at the same time. If you find that you need to add a condition on the column NAME, you add WHERE NAME = :1 to the SQL string and a parameter with name :1 and the value you wish to add. If you have a second condition to add, you append AND ID = :2 to the SQL string and a parameter with name :2.
Hopefully the following code should explain a little better:
// Initialise SQL string and parameter list.
String sql = "SELECT * FROM DUAL";
var oracleParams = new List<OracleParameter>();
// Build up SQL string and list of parameters.
// (There's only one in this somewhat simplistic example. If you have
// more than one parameter, it might be easier to start the query with
// "SELECT ... FROM some_table WHERE 1=1" and then append
// " AND some_column = :1" or similar. Don't forget to add spaces!)
sql += " WHERE DUMMY = :1";
oracleParams.Add(new OracleParameter(":1", OracleDbType.Varchar2, "X", ParameterDirection.Input));
using (var connection = new OracleConnection() { ConnectionString = "..."})
{
connection.Open();
// Create the command, setting the SQL text and the parameters.
var command = new OracleCommand(sql, connection);
command.Parameters.AddRange(oracleParams.ToArray());
using (OracleDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// Do stuff with the data read...
}
}
}