Getting a String from a value in Mysql in C# - c#

i have the following table in MySql :
ID Name
1 Google
2 Yahoo
3 Facebook
4 Whatever
I have a textfield that when someone writes something and presses a button it stores this value in a string. This string is the Name of the above table. Then i have my code about selecting the id referred to that name. Ex, if the user enters Facebook i will find that the ID = 3. this is the code :
public bool FindCompanyID(string companyName)
{
return ExecQuery("select id from companies where name=#name",
cmd =>
{
cmd.CommandText = "SELECT id from companies WHERE name ='" + companyName + "'";
return cmd;
});
}
I want someone to show me a sample of code about the following : Saving to a string the " id " . if the ID in the database = 2 i want to make a
int Company_Number_ID
that i will use. How can i get the string to read the specified value from the database?

I am guessing your return type is bool to check whether the DDL statements were executed successfully.
MySqlCommand cmd = dbConn.CreateCommand();
cmd.CommandText = "SELECT id from companies WHERE name ='" + companyName + "'";
try
{
dbConn.Open();
Company_Number_ID = (Int32)cmd.ExecuteScalar();
} catch (Exception e) {
//Exception occured. Handle it here
}
Note: cmd.Parameters.AddWithValue("#companyName",companyName).
this is more secure
Edit: As pointed out in the comment by user3185569 , ExecuteScalar is better if you are sure it'll return only one row. But since no such information was provided. I did not consider that.
You can use ExecuteScalar directly like this.
Company_Number_ID = (Int32)cmd.ExecuteScalar();

Related

IndexOutOfRange Exception in sqldatareader using c#

I create an application using c# , In my authentification interface , i have a test control , i want to know profile user .
My database contains table named user which contains 4 columns
(id_user,name ,mail, profile)
Here is my code
public string profil_user(string login)
{
SqlConnection conn = new database().connect_user();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = "select profile from user where name = '" + login + "';";
SqlDataReader s = cmd.ExecuteReader();
if (s.Read())
{
return ( s.GetString(3));
}
else{return ("false"); }
}
but i have an exception in s.GetString(3)
system.IndexOutOfRange : index was outside the bounds of the array
You're only selecting a single field (profile) but then you're trying to select the 4th field (index 3) here:
return ( s.GetString(3));
In addition to just returning s.GetString(0) I would strongly advise you to:
Use parameterized SQL - always do this, to prevent SQL injection attacks, make your code more readable, and prevent unexpected text conversion problems
Either throw an exception or return null if the profile isn't found, instead of returning the string "false"
Use using statements for disposable things like SqlCommand, SqlConnection and SqlDataReader to ensure that you clean up resources appropriately
Start following .NET naming conventions to make your code more idiomatic
So something like:
public string GetUserProfile(string login)
{
string sql = select profile from user where name = #login";
// I assume Connect() returns an *open* connection?
using (var conn = new Database().Connect())
{
using (var command = new SqlCommand(sql, conn))
{
command.Parameters.Add("#login", SqlDbType.NVarChar).Value = login;
using (var reader = command.ExecuteReader())
{
// If it's an error (code failure) for there to be no matching profile,
// you may want to throw an exception instead.
return s.Read() ? s.GetString(0) : null;
}
}
}
}
So you want the fourth row, not the fourth column which you try to access with s.GetString(3):
int rowNum = 0;
while(s.Read())
{
if(++rowNum == 4)
{
return s.GetString(0);
}
}
return "false";
However, it is a bit strange to access the fourth row when you don't use an Order By. You should also only return the row that you want with the correct sql query.
You are also open for sql injection if you use string concatenation here:
cmd.CommandText = "select profile from user where name = '" + login + "';";
Use sql parameters:
cmd.CommandText = "select profile from user where name = #login";
cmd.Parameters.Add("#login", SqlDbType.VarChar).Value = login;
have 4 columns not rows
Ok, so you instead want the fourth column. Why don't you use the name instead?
Since you only select the profile-column(the fourth), you could simply use GetString(0). But you could also select all columns and then determine the correct index with GetOrdinal:
int profileColumnIndex = s.GetOrdinal("profile");
return s.GetString(profileColumnIndex);
This is useful if you don't control the query or it might be changed in future.
You are selecting only 1 field, thus index 3 is out of bounds. It also very important to Use parameters. Try:
cmd.CommandText = "select profile from user where name = #login;";
cmd.Parameters.Add("#login, SqlDbType.NVarChar).Value = login;
SqlDataReader s = cmd.ExecuteReader();
while (s.Read())
{
return s[0].ToString();
}
The parameter for SqlDataReader.GetString should be the column index. You're only selecting one column so you get an exception.
Because you do not have all the fields in your select list
Change the SQL to:
select id_user,name ,mail, profile from user where name = '" + login + "';

Parameterized query not working in C#

I am currently in a corner and have no idea why the following code will not execute properly and update the database (Access).
newUser = All of the new user's data including their ID
list = Contains a list of GermanResources (class) entries that correspond to the pages checkboxes. Class includes .Name (text value of checkbox) and .Value (checked? 1 or 0)
I want to update the database with the checkbox value of each GermanResource.
IF i replace #acc_Value with the value 1 this code works. It seems to not work with the first parameter in place. Debugging this showed me that everything had the proper values at the proper times and since "1" worked I know the data types are not mismatched.
Note: There were no errors with or without the parameter in place.
I would appreciate any input about this.
This is one of the CommandTexts that are generated:
UPDATE VMS_GRM_GermanResource_Access SET VTOFZN = #acc_Value WHERE UserId = #userId
private bool NewUser_Insert_GermanResourceAccess(OleDbConnection connection, User newUser, List<GermanResource> list)
{
bool result = false;
try
{
foreach (var item in list)
{
string column = item.Name.Replace(" ", "");
string query = #"UPDATE VMS_GRM_GermanResource_Access SET " + column + " = #acc_Value WHERE UserId = #userId";
OleDbCommand command = new OleDbCommand(query, connection);
command.Parameters.AddWithValue("#userId", newUser.Id);
command.Parameters.Add(new OleDbParameter("#acc_Value", OleDbType.Integer, 1));
command.Parameters["#acc_Value"].Value = item.Access;
command.ExecuteNonQuery();
}
result = true;
}
catch (OleDbException ex)
{
UADConnection.Close();
MessageBox.Show(ex.ErrorCode.ToString() + ": " + ex.Message);
return result;
}
return result;
}
Use this to prepare sql statement :-
string query = #"UPDATE VMS_GRM_GermanResource_Access SET column_name=" +
#acc_Value + " WHERE UserId = " +#userId+";
#Tetsuya Yamamoto:
OLEDB parameters were not in order according to the query. Swapping them around to match the order in the query set things straight. All good again and thanks for everyone's inputs.

C# SQL : update with params - getting 0 and without the text

I am making DatabaseManager class for my solution and I am getting the number 0 when I am trying to update the text.
For example : I have now the name michael and I wanted to change it to "michael , mike" so I'll probably use update.
public void AddCrime(CSteamID id, string crime, string time)
{
try
{
MySqlConnection connection = createConnection();
MySqlCommand command = connection.CreateCommand();
crime = "," + crime;
command.CommandText = "update `" + Main.Instance.Configuration.Instance.DatabaseTableName
+ "` set `crime` = crime + ( #crime ) where `steamId` = #steamID; select `crime` from `"
+ Main.Instance.Configuration.Instance.DatabaseTableName
+ "` where `steamId` = #steamID";
command.Parameters.AddWithValue("#steamID", id);
command.Parameters.AddWithValue("#crime", crime);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
AddTime(id, time);
}
catch (Exception ex) { Logger.Log(ex); }
}
How do I call it :
DatabaseManager.AddWanted(player.CSteamID, command[1], command[2]);
Thanks everyone!
yor last sentence in your command is a select statement, NonQuery does not return values, only the number of rows affected. Change it to ExecuteScalar and store the value of the select in a variable.
Second error is the data type of the parameter #steamID. You set the value id, which is declares as CSteamID id... CStreamId is not string, change the AddWithValue
Fixed, I added another method to get crime from table and then changed the void crime string to the current string + the table text.
The error was : Truncated incorrect DOUBLE value.

C# Oracle table issue

I've got a problem with my ASP.NET application when I'm trying to log in a user. The issue is that when I'm trying to run the query, an exception gets thrown which says the tale name is invalid. It's because the table is called USER, which is a part of SQL.
I'm not in a position where I can change the table name.
public bool LoginUser(string username, string password)
{
//Database Connectie maken
DBConnectionOpen();
string query = #"SELECT NICKNAME, PASSWORD FROM " + "'USER'" + "WHERE NICKNAME = '" + username + "'";
bool result = false;
try
{
OracleCommand command = new OracleCommand(query, conn);
OracleDataReader reader = command.ExecuteReader();
Console.WriteLine("*Query Uitvoeren*");
reader.Read();
if (username + password == reader.GetString(0) + reader.GetString(1))
{
result = true;
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
}
return result;
}
Whomever named the table "USER" should have db privs removed, but I think you just need to add double quotes around the table name:
select * from "USER" where ...
Note that its case sensitive when you add the double quotes, so if the table is named User you'd need "User" instead of "USER"
Thanks for all the response, but I finally figured it out.
What the query should have been:
string query = #"SELECT NICKNAME, ""PASSWORD"" FROM ""USER"" WHERE NICKNAME = '" + username + "'";
You are querying on the string value 'USER'.
You should use
string query = #"SELECT NICKNAME, PASSWORD FROM [USER] WHERE NICKNAME = '" + username + "'";
This will query on the table called USER. In SQL normally you use brackets to indicate you are querying on an object if what you mean can be ambiguous.
The concatenation of the table name as a string is unnecessary so I left it out. If you change it to a variable it can be useful.
In addition instead of concatenating username maybe you should also use alternative for Oracle what is called SqlParameter for SQL Server, to avoid SQL injection.
Try to correct your SQL statement like the following:
string query = "SELECT NICKNAME, PASSWORD FROM [USER] WHERE NICKNAME = '" + username + "'";
Also, if you are using SQL reserved word (e.g. DATE) as a Column name, then enclose it in angular brackets (like [DATE]) in your SQL statement.
Hope this may help.

Checking for Primary Key assignment

I have a web application that writes to several databases for tracking employee change requests. I am running into a problem with entering in a new employee. They are first written to main Employee database before their access information is written to the other databases with EMP_ID being the primary key. When it goes to write to the other databases EMP_ID has been generated yet so it is getting entered in as 0.
To resolve this I was trying to loop and check the EMP_ID value until a value is generated but I continue to get stuck in a loop because the query returns back that no value was found.
while (int.Parse(empIDChecker) == 0)
{
dbConnection.Open();
validateIDSQLString = "SELECT EMP_ID FROM EMPLOYEE_TABLE WHERE FIRST_NAME = '" + firstNameTextBox.Text.Trim() + "' AND LAST_NAME = '" + lastNameTextBox.Text.Trim() + "'";
SqlCommand updateSQLCmd = new SqlCommand(validateIDSQLString, dbConnection);
SqlDataReader getRecords = updateSQLCmd.ExecuteReader();
try
{
empIDChecker = getRecords["EMP_ID"].ToString();
}
catch
{
empIDChecker = "0";
}
getRecords.Close();
dbConnection.Close();
}
OK, so if your insert sproc looks something like:
sp_InsertEmp
...
INSERT INTO Emp(Name, etc...)
VALUES ('Paul', etc...)
SELECT SCOPE_IDENTITY() AS EMP_ID
GO
And in your code:
SqlCommand insertCmd = new SqlCommand("sp_InsertEmp", dbConnection);
... Add parameters here and set type to StoredProcedure
SqlDataReader dr= insertCmd.ExecuteReader();
int newId;
if (dr.Read())
{
newId = dr.GetInteger(0);
}
you can use
SELECT IDENT_CURRENT(‘tablename’)
This will give you the last inserted auto increment ID of the table, you can use that to insert in other table
Check this link as well http://blog.sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record/

Categories