C# Reusable Mysql Class - c#

I am having some issues with a class that I have created to perform different database commands.
1st) The program is local ran, and will only run locally. It will only ever connect to the database on the localhost.
Therefore I have a simple class setup, called databaseConnector that allows me to pass a string to it with the required Mysql query to perform the different functions.
For instance.
I use:
var db = new databaseConnector();
db.Update("UPDATE * WHERE.....");
However, it seems if I ever want to use a different query, or another query, it's not working and throwing errors.
For instance.
var db = new databaseConnector();
db.Update("UPDATE * WHERE...");
db.INSERT("INSERT INTO * WHERE.....");
Will give me an error on the insert execution. Any ideas why? I have resorted to creating it again. So I have to redo:
db = new databaseConnector();
to then use the Insert command.
Here is an example of my insert function.
public void Insert(string query)
{
//open connection
if (this.OpenConnection() == true)
{
//create command and assign the query and connection from the constructor
MySqlCommand cmd = new MySqlCommand(query, connection);
//Execute command
cmd.ExecuteNonQuery();
//close connection
this.CloseConnection();
}
}
Now that I think about it. Should I call my db.openConnection() before doing it. Since when I initialize it in the first var db = new databaseConnection(), it's opening? And then in each function it's closing it, but only checking if it's open, instead of attempting to open, doing query, then closing.

Related

How to Fix CA2100: SQL security vulnerability In Legacy code when SQL query is coming to function from outside of it?

While working on legacy code, I ran into Specific scenario and made a dummy example to show the issue to ask for any suggestions. I get following error:
`
Program.cs(37,1) : warning : CA2100 : Microsoft.Security : The query string passed to 'OleDbCommand.CommandText.set(string)' in 'Program.Read(OleDbConnection, string)' could contain the following variables 'sqlQuery'. If any of these variables could come from user input, consider using a stored procedure or a parameterized SQL query instead of building the query with string concatenations.
My Code is:
class Program
{
static void Main ()
{
string connectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Newfolder\database1.mdb";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
try
{
connection.Open();
string strsql = "SELECT * FROM Table1";
Read(connection,strsql);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
static void Read (OleDbConnection connection,string sqlQuery)
{
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = sqlQuery;
OleDbDataReader reader = command.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(reader["PName"]);
}
}
}
Now I cannot go with the solution to suppress warning. There are several complicated situations from which i get these warnings, this is just a dummy simple example to show workflow.
So although the query being executed is safe, but since it comes outside of the function, it asks me to changed it to parametrized query.
As in Read() function, although my input paramter sqlQuery is not from user, but it will come from outside as an input parameter and I cannot move sqlQuery code within the Read() function, it will always come from outside based on which certain decisions are made.
So what can I do to make this redundant warning disapper?
My dummy Access databse snapshot is this:
I have tried going through Microsoft official documentation on it, but i was not able to come up with solution

Why is the inserted value only visible while the program is running?

my problem is currently that I add a player to the database and that player is visible only as long as the program runs.
The test() method should add a player to the database.
private static void Test()
{
SqlConnection connection;
string connectionString = ConfigurationManager.ConnectionStrings["Footbal.Properties.Settings.cn"].ConnectionString;
connection = new SqlConnection(connectionString);
connection.Open();
string query = "INSERT INTO Players(id, player_name, player_price, player_rating) VALUES(#id, #player_name, #player_price, #player_rating)";
string name = "Ronaldo";
SqlCommand testInsert = new SqlCommand(query, connection);
testInsert.Parameters.AddWithValue("#id", 43);
testInsert.Parameters.AddWithValue("#player_name", name);
testInsert.Parameters.AddWithValue("#player_price", 34);
testInsert.Parameters.AddWithValue("#player_rating", 54);
testInsert.ExecuteScalar();
connection.Close();
}
After this method the DataGridView is filled. (playersTableAdapter acts as a bridge between DataSet(db_PlayersDataSet.Players) and database)
playersTableAdapter.Fill(db_PlayersDataSet.Players);
So far everything works as expected. And now when I close the program, the added data is gone.
What is the problem?
I suspect you're using an attached-when-the-program-runs database, meaning that when the project is run a new database (copied from the project folder) is output and attached
Attach your db permanently and adjust your connstr, or just accept the behavior; it'll be fine when the app is deployed
In your test() method, you need to use ExecuteNonQuery() instead of ExecuteScalar(). Just change below line in above code and it should work.
Change
testInsert.ExecuteScalar();
to
testInsert.ExecuteNonQuery();
Is "Id" Primary Key in the database?
Did you try to insert without "Id", or to use different "Id" for new player?

Using DbConnection without opening it first

I am accessing a DB using the generic DbConnection provided by DbProviderFactories and I have observed that I don´t need to call Open before using the connection. I provide a sample code that is working (either using "System.Data.SqlClient" or "Oracle.DataAccess.Client" as the providerInvariantName parameter). I have performed all CRUD operations with similar code without explicitly calling Open on the connection, without any noticeable error.
I understand that I don´t need to close it, since the using statement takes care of closing and disposing the connection.
But, when is the connection opened in this code, then? Is it automatically opened when I call Fill on the associated DataAdapter? Is there any consequence of not explicitly calling Open on the connection object before using it?
Because if it is unnecesary and I can save myself a couple of lines of code I will sure do. ;-)
DbProviderFactory myFactoryProvider = DbProviderFactories.GetFactory("System.Data.SqlClient");// same with "Oracle.DataAccess.Client"
using (var myConnection = myFactoryProvider.CreateConnection())
using (var myCommand = myFactoryProvider.CreateCommand())
{
try
{
// Set up the connection
myConnection.ConnectionString = _someConnectionString;
myCommand.Connection = myConnection;
myCommand.CommandText = "SELECT * FROM SOME_TABLE";
// Create DataAdapter and fill DataTable
DbDataAdapter dataAdapter = myFactoryProvider.CreateDataAdapter();
dataAdapter.SelectCommand = myCommand;
DataTable myTable = new DataTable();
dataAdapter.Fill(myTable);
// Read the table and do something with the data
foreach (DataRow fila in myTable.Rows)
{
// Do something
}
}
catch (Exception e)
{
string message = e.ToString();
throw;
}
} //using closes and disposes the connection and the command
The connection to the db should be established and opened when the statement
dataAdapter.Fill(myTable);
runs, so your code goes well as is

C# MySql force blocking mode

I have the following code:
static void InsertRes(string Data)
{
string query = "INSERT INTO results (gamenum,result) " + Data;
query += ";";
//open connection
if (OpenConnection() == true)
{
//create command and assign the query and connection from the constructor
MySqlCommand cmd = new MySqlCommand(query, connection);
//Execute command
cmd.ExecuteNonQuery();
//close connection
CloseConnection();
}
}
I know it's not the best practices but I generate data within my application, how can I force this function to block until the query has been successfully executed upon the mysql database?
It will do that automatically.
cmd.ExecuteNonQuery(); will return after the insertion is finished.
That is standard programming behaviour. Doing multiple task simultaniously is where it gets tricky. Doing one thing after the other is just normal. Your program will continue to the next line only when the execution if the preivious line is finished.

How to call multiple stored procedures in a MySql database

I am able to get this program to work with one stored procedure. Is it possible to call multiple stored procedures from MYSQL in C#? If so what is the most efficient way of doing so? Here is a snippet of my code to show what I've done thus far:
public static string RunSQL()
{
// Here is where it is connecting to local host.
string connStr = "server=localhost;user=xxxx;"
+ "database=xxxx;port=3306;password=xxx;"
+ "Allow User Variables=True";
MySqlConnection conn = new MySqlConnection(connStr);
// Here is where the connection gets opened.
conn.Open();
// Here I call the CN_renumber stored procedure.
MySqlCommand CN_renumber = new MySqlCommand("CN_renumber", conn);
CN_renumber.CommandType = System.Data.CommandType.StoredProcedure;
object result = CN_renumber.ExecuteNonQuery();
// Disconnect from local host.
conn.Close();
return result.ToString();
}
You can reuse your object of MySQLCommand multiple times, but before that you should make sure you call myCommand.Parameters.Clear();, then assign the new Stored Procedure name again.
Useful question with example here

Categories

Resources