Do parameterized queries work with MySQL in c#? [duplicate] - c#

This question already has answers here:
Parameterized Query for MySQL with C#
(6 answers)
Closed 4 years ago.
I am attempting to run a query using a parameter in C#. I am getting an issue where no rows are being returned. I am pulling the sql from a file and putting it into the command text. When the query (a SELECT statement) is run, no results are returned. I have confirmed that the result is in my database and that the query is correct (after replacing the param) by running it normally.
conn.Open();
//create the command
var command = conn.CreateCommand();
//Read sql from file
FileInfo file = new FileInfo("SQL/GetPage.sql");
string script = file.OpenText().ReadToEnd();
command.CommandText = script;
command.Parameters.AddWithValue("?PageID", PageName);
command.Prepare();
MySqlDataReader rdr = command.ExecuteReader();
rdr.Read();
SQL:
SELECT * FROM `Page` WHERE PageID = '?PageID'
I have tried with both the prepare and without it. I have no clue why it is not working. Also, I am only expecting one result max (PageID is unique), so that is why it isn't in a loop. I also know my connection is good because I hardcoded the query without the where clause and it worked fine.
Please let me know if anyone has any suggestions.
Thanks

Read() just advances the DataReader to the next record (this is why it used in a loop). You need to extract the data from this record
while (rdr.Read())
{
int i = rdr.GetInt32(0);
string s = rdr.GetString(1);
}

Related

Retrieving image from SQL Server to ASP.NET imagebutton [duplicate]

This question already has answers here:
Creating a byte array from a stream
(18 answers)
Closed 2 years ago.
I am trying to insert data from ASP.NET into SQL Server and retrieve it from SQL Server back to ASP.NET.
The insert part is done, but I am having problems to retrieve data. I am using this code, but is throwing an error:
SqlConnection con = new SqlConnection(myconnstrng);
con.Open();
SqlCommand cmd = new SqlCommand("selection", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", parameter);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet dsa = new DataSet();
da.Fill(dsa);
if (dsa.Tables[0].Rows.Count > 0)
{
MemoryStream ms = new MemoryStream((byte[])dsa.Tables[0].Rows[0]["Data"]);
string strBase64 = Convert.ToBase64String(ms);
ImageButton2.ImageUrl = "data:Image/png;base64," + strBase64;
}
and the error I got is :
Cannot convert from 'System.IO.MemoryStream' to 'byte[]'
I am new to programming, and if someone could help me about this problem.
Thanks to everyone !
The particular line you are stuck on, you don't need a MemoryStream at all. You can pass the value from the DataTable straight to ToBase64String.
But you can save yourself some bother with these tips:
ALWAYS dispose the connection, command and adapter/reader correctly, by putting them in using blocks`
For a single result, you can skip the table and adapter, and just use (byte[]) cmd.ExecuteScalar().
If you have more than one row which you need to process (as opposed to just displaying in a grid view), you may find it again easier to skip the DataTable and grab data out via this:
using(var reader = cmd.ExecuteReader())
{
while(reader.Read())
DoSomethingWithResult(reader.IsDBNull(0) ? null : reader.GetBytes(0));
}
Generally, DoSomethingWithResult should not be very heavy processing, or you will block the SQL server. If so, store in memory and process it afterwards.

how to display database value in console in c#

How to display the unitfunction value from mysql database and my query is below ,i don't know its right or wrong.
Help me out.
string fundev = "select unitfunctioncode from channels where channel_no = " + Channelid;
MySqlCommand getfun = new MySqlCommand(fundev, Connection1);
Console.WriteLine(getfun);
MAKE ENTITY CONTEXT FIRST:
YourEntity db= new YourEntity();
LINQ:
Console.Write(db.channels.Where(x=>x.channel_no == Channelid).Select(y=>y.unitfunctioncode));
This is modal first approach create modal from database and call this linq in controller
I'm not sure about the specifics of MySqlCommand, but I would expect to see an execute on your getfun object.
I would do something like this:
MySqlDataReader rdr = getfun.ExecuteReader();
while (rdr.Read())
{
Console.WriteLine(rdr[0]);
}
rdr.Close();
This takes into account multiple rows returned. You can omit the while loop if you're sure you will have a single row returned.

A generic function that will return the results of a SELECT query from a local MySQL database - C# .Net 4.6.1

I'm using a MySQL local database, connecting to the database is not a problem (anymore). I have a small-scale database with around 6 different tables, each with around 4-6 columns, and rows <100 (not working with large data).
I am creating a WPF application that only ever needs to SELECT data from these databases, it never needs to add to them. The database is filled with static data which I will need to run SELECT statements on it and then use the results to display in my WPF app.
I need to make a function in my DBHandler class which can then be called from any other class in my system, to query the database with a specified SELECT statement, and then use the results. The problem is that my queries will vary - sometimes I might be calling for one column, such as;
(SELECT id FROM students WHERE name = 'Conor')
Sometimes I might be calling for multiple rows in a more complex statement.. such as this (pseudo):
(SELECT name, address FROM destinations WHERE long, lat intersects_with (SELECT long, lat FROM trains))
Whenever I call this function with a query, I will always be expecting the format of the data response, so if I just return a List<> or array, it should be no problem accessing the data even though the function is generic and not specific for one query or table.
So far I have tried this:
public static MySqlDataReader Query(string SQLQuery)
{
using (MySqlConnection con = new MySqlConnection(connectionString))
{
con.Open();
MySqlCommand command = new MySqlCommand(SQLQuery, con);
MySqlDataReader reader = command.ExecuteReader();
return reader;
}
}
// Some other class
MySqlDataReader reader = DBHandler.Query("SELECT * FROM destinations");
while (reader.Read())
{
MessageBox.Show(reader[0].ToString());
}
This doesn't work, because it complains the reader is closed. I presume I can't simply return a MySqlDataReader object.
My next thought process would be to do the actual query and return all the data in this Query function, and store all the results which can then be returned. But how I return the data is my main issue, because it needs to be generic for variable SELECT queries, so it can't have a fixed size for number of rows or columns returned. I thought maybe I could store it in a List<>, or a List<> within a List<>, but I'm really not sure on how to lay it out.
I know this is asking a lot but it is boggling my mind - I don't know how to make this generic SELECT function, but I know it will be really helpful as I will just need to call this whenever I need to get data in another part of the system.
Thank you!
You cannot try to use a DataReader when its connection has been closed. So, when your code exits the using block, the connection is closed as well the reader. However, you can pass to your Query method an Action delegate that receives a MySqlDataReader. This function will be defined by the caller of Query so you can customize it for your different tables while keeping a generic approach to the boilerplate code used to open, query and read the database.
public static MySqlDataReader Query(string SQLQuery, Action<MySqlDataReader> loader)
{
using (MySqlConnection con = new MySqlConnection(connectionString))
{
con.Open();
using(MySqlCommand command = new MySqlCommand(SQLQuery, con))
using(MySqlDataReader reader = command.ExecuteReader())
{
// here you can pass the reader, you are still inside the using block
while(reader.Read())
loader.Invoke(reader)
}
}
}
In the caller code you could write
List<Destination> destinations = new List<Destination>();
MySqlDataReader reader = DBHandler.Query("SELECT * FROM destinations", dataLoaderForDestination);
Console.WriteLine("Loaded " + destinations.Count + " destinations");
private void dataLoaderForDestination(MySqlDataReader reader)
{
Destination dest = new Destination();
dest.Address = reader.GetString(0);
dest.Nation = reader.GetInt32(1);
...
destinations.Add(dest);
}
Of course in a different point of your code you could pass the reference to a different Action delegate tailored for a different set of data returned by your query
List<Student> students = new List<Student>();
private void dataLoaderForStudents(MySqlDataReader reader)
{
Student st = new Student();
st.Name = reader.GetString(0);
st.Class = reader.GetInt32(1);
students.Add(st);
}
a reader is online, you need to loop inside (using connection), because if you leave the using, the connction is disposed and closed

Checking and Saving/Loading from MySQL C#

I am making something that requires MySQL. I have the saving done from in-game, which is simply done by INSERT.
I have a column that will have a password in and I need to check if the inputted password matched any of the rows and then if it is, get all of the contents of the row then save it to variables.
Does anyone have an idea how to do this in C#?
//////////////////////////
I have found how to save and get the string, however it will only get 1 string at a time :(
MySql.Data.MySqlClient.MySqlCommand command = conn.CreateCommand();
command.CommandText = "SELECT * FROM (player) WHERE (pass)";
command.ExecuteNonQuery();
command.CommandType = System.Data.CommandType.Text;
MySql.Data.MySqlClient.MySqlDataReader reader = command.ExecuteReader();
reader.Read();
ayy = reader.GetString(1);
print (ayy);
if(ayy == password){
//something
}
My best practice is to use MySQLDataAdapter to fill a DataTable. You can then iterate through the rows and try to match the password.
Something like this;
DataTable dt = new DataTable();
using(MySQLDataAdapter adapter = new MySQLDataAdaper(query, connection))
{
adapter.Fill(dt);
}
foreach(DataRow row in dt.Rows)
{
//Supposing you stored your password in a stringfield in your database
if((row.Field<String>("columnName").Equals("password"))
{
//Do something with it
}
}
I hope this compiles since I typed this from my phone. You can find a nice explanation and example here.
However, if you are needing data from a specific user, why not specificly ask it from the database? Your query would be like;
SELECT * FROM usercolumn WHERE user_id = input_id AND pass = input_pass
Since I suppose every user is unique, you will now get the data from the specific user, meaning you should not have to check for passwords anymore.
For the SQL statement, you should be able to search your database as follows and get only the entry you need back from it.
"SELECT * FROM table_name WHERE column_name LIKE input_string"
If input_string contains any of the special characters for SQL string comparison (% and _, I believe) you'll just have to escape them which can be done quite simply with regex. As I said in the comments, it's been a while since I've done SQL, but there's plenty of resources online for perfecting that query.
This should then return the entire row, and if I'm thinking correctly you should be able to then put the entire row into an array of objects all at once, or simply read them string by string and convert to values as needed using one of the Convert methods, as found here: http://msdn.microsoft.com/en-us/library/system.convert(v=vs.110).aspx
Edit as per Prix's comment: Data entered into the MySQL table should not need conversion.
Example to get an integer:
string x = [...];
[...]
var y = Convert.ToInt32(x);
If you're able to get them into object arrays, that works as well.
object[] obj = [...];
[...]
var x0 = Convert.To[...](obj[0]);
var x1 = Convert.To[...](obj[1]);
Etcetera.

Delete file from server

I have an application that I am using as a file uploader with an admin panel on the backend of things. I have most of everything completed on it, but I'm running into a wall where I can't delete the physical file from the server. Permissions are correct to allow such action.
On the click of a delete button next to the entry I'm calling the primary ID of the row and as such I'm able to call from the SQL the stored filePath. Here's my code to do so:
DbConn dbConnx = new DbConn();
SQL = "SELECT filePath FROM database WHERE id='"+ primaryID +"'";
myReader = dbConnx.createDataReader(SQL);
string fn44 = Convert.ToString(myReader.Read());
string url = fn44; //I know redundant
System.IO.File.Delete(url);
All I'm able to gather is that the only information that is pulled is 'true'. I believe this is because I'm trying to convert the information to a string and it doesn't like that. How would I go about taking the value stored in SQL and using it with a variable to perform the delete?
Any help/resources would be greatly appreciated.
I don't know the datatype of myReader, but assuming that is a DataReader of some kind then calling
myReader.Read();
returns a boolean value that tells you if the datareader is positioned on a valid row or not.
To get the content of the record on which the reader is positioned (assuming the previous call returns true) you need to write
myReader = dbConnx.createDataReader(SQL);
if(myReader.Read())
{
string fn44 = Convert.ToString(myReader[0]);
....
}
Your code has another problem called Sql Injection.
You should not use string concatenation with user input when building a sql command.
You use a parameterized query like this
SQL = "SELECT filePath FROM database WHERE id=#p1";
using(SqlConnection con = new SqlConnection(......))
using(SqlCommand cmd = new SqlCommand(SQL, con))
{
con.Open();
cmd.Parameters.AddWithValue("#p1",primaryID);
using(SqlDataReader myReader = cmd.ExecuteReader())
{
.....
}
}
yyy
Having fixed the reading from the database, now you need to check what kind of string is stored in the FilePath field in the database. Remember that every file IO operation on a web site should get to the effective file name using the Server.MapPath method

Categories

Resources