C# use a reader in another reader solution? - c#

I need to get some mysql data into another mysql reader request anyway to workaround that I apparently can't have 2 readers open at the same time it will all end up in a datagrid
public void DBSelectPraktikanter(object sender)
{
string Command = "SELECT * FROM forlob WHERE firmaid = N'" + firmaid + "'";
MySqlConnection sqlConnection1 = new MySqlConnection(connectionString);
MySqlCommand command = new MySqlCommand(Command, sqlConnection1);
sqlConnection1.Open();
MySqlDataReader reader = command.ExecuteReader();
var items = new List<praktikanter>();
if (reader.HasRows)
{
while (reader.Read())
{
string praktikantid = String.Format("{0}", reader["praktikantid"]);
string Command2 = "SELECT * FROM praktikanter WHERE id = N'" + praktikantid + "'";
MySqlCommand command2 = new MySqlCommand(Command, sqlConnection1);
MySqlDataReader reader2 = command.ExecuteReader();
if (reader.HasRows)
{
while (reader2.Read())
{
Praktikant = String.Format("{0}", reader["Navn"]);
}
}
string Fra = String.Format("{0}", reader["fra"]);
string Til = String.Format("{0}", reader["til"]);
items.Add(new praktikanter(Praktikant, Fra, Til));
}
}
sqlConnection1.Close();
var grid = sender as DataGrid;
grid.ItemsSource = items;
}

Instead of nesting MySqlCommands and looping the first resultset to query again the database to collect all of your data you should really use one query. Also use the using-statement to ensure that the connection gets closed even on error and use sql-parameters to avoid sql-injection issues:
var items = new List<praktikanter>();
string sql = #"SELECT p.*, f. Navn
FROM praktikanter p INNER JOIN forlob f ON p.id = f.praktikantid
WHERE f.firmaid = #firmaid";
using (var con = new MySqlConnection(connectionString))
using (var command = new MySqlCommand(sql, con))
{
command.Parameters.Add(new MySqlParameter("#firmaid", MySqlDbType.VarChar).Value = firmaid);
con.Open();
using (var rd = command.ExecuteReader())
{
while (rd.Read())
{
string praktikant = rd.GetString("Navn");
string fra = rd.GetString("Fra");
string til = rd.GetString("Til");
items.Add(new praktikanter(praktikant, fra, til));
}
}
}

Related

How to concatenate query result in C#

I want to concatenate the query result in c#. Below is the resulting image
In my code, I have done
using (MySqlConnection cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`read_param` FROM mdc_request m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", iterations.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
// here I want to save the result in one single variable
}
}
Update 1
As per #Rahul answer, I have done the following
public async Task YtlbusMethod(List<Iterations> ytlbus)
{
MySqlConnection cn = null;
int limitRequest = 10;
for (int i = 10; i > 0; i--)
{
foreach (var item in ytlbus)
{
using (cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`time` FROM `mdc_meter_config` m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", item.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
string time = (string)reader["time"];
if(item.time == time)
{
int sleeptime = Convert.ToInt32(item.time);
sleeptime = sleeptime * 1000;
Thread.Sleep(sleeptime);
Task.Factory.StartNew(() => PortHitmethod(item));
}
}
}
cn.Close();
// select query kerni hy ..jis main wohi data ay jo tu yahan pass ker raha hy... where k ander just tuny row id pass kerni hy.
//if(item.time== query main jo time aya hy woh)
//{
//}
}
}
}
public async Task PortHitmethod(Iterations iterations)
{
MySqlConnection cn = null;
List<string> data = new List<string>();
using (cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`read_param` FROM mdc_request m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", iterations.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
data.Add(reader["read_param"].ToString());
}
}
cn.Close();
var single = string.Join("", data);
}
Now the issue that I am facing is that I am unable to get all the rows data. The total rows are 9 but I am getting less than that
How can I achieve this? Any help would be highly appreciated.
Looks like those are integer value then you can do something like
List<int> data = new List<int>;
while (reader.Read())
{
data.Add(int.Parse(reader["read_param"].ToString()));
}
Then you can use string.Join() method like
var single = string.Join(",", data);
Based on #Rahul, your code should be:
Your update 1 is different code.
What do you want to achieve here.
List<string> data = new List<string>();
using (MySqlConnection cn = new MySqlConnection(conn.ConnectionString))
{
string query = "SELECT m.`read_param` FROM mdc_request m WHERE m.`row_id` = #row_id";
cn.Open();
MySqlCommand cmd = new MySqlCommand(query, cn);
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#row_id", iterations.row_id);
reader = cmd.ExecuteReader();
while (reader.Read())
{
data.Add(reader["read_param"].ToString());
}
}
var single = string.Join("", data);

How to make an "if" based on value retrieved from Query?

I need to insert into a table "pass" or "fail", if from the query done there is a single fail instead of 'RProva' I have to put "fail" if the query can't find a single fail instead of 'RProva' I have to insert "pass", the query is working but I can't figure out how to do the if with the results of a query, maybe I have to use a "for"? Don't know. It is the attempt to make it, the second is the query where I have to insert the result of the possbile "IF"
1.
SqlCommand cmdRD = new SqlCommand("SELECT ResItem AS RD FROM tSE JOIN tL ON tSE.idSE=tL.idL WHERE tL.Selection=1");
var RD = cmdRD.ExecuteScalar();
var values = new List<string>();
using (cmdRD,sqliteCon)
{
using (SqlDataReader reader = cmdRD.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader[0].ToString());
}
}
}
2.
SqlCommand cmd1 = new SqlCommand("INSERT INTO tSD(NomeItem,ResItemDet,DateStartDet,DateEndDet) OUTPUT inserted.Id VALUES (#NI,#RProva,#DATESE,#DATEED)");
cmd1.Parameters.AddWithValue("#DATESE", DATESE);
cmd1.Parameters.AddWithValue("#DATEED", DATEED);
cmd1.Parameters.AddWithValue("#NI", NI);
using (cmd1,sqliteCon)
{
foreach (var value in values)
{
if (value.Equals(pass))
{
cmd1.Parameters.AddWithValue("#RProva", value);
}
else
{
cmd1.Parameters.AddWithValue("#RProva", fail);
}
cmd1.ExecuteNonQuery();
}
}
int generatedId = Convert.ToInt32(cmd1.ExecuteScalar());
cmd1.Parameters.Clear();
SqlCommand cmd2 = new SqlCommand("UPDATE tSE SET FK_TSD_id = #tsdId FROM tL JOIN tSE ON tL.idL = tSE.idSE WHERE tL.Selection=1 ", sqliteCon);
cmd2.Parameters.AddWithValue("#tsdId", generatedId);
cmd2.ExecuteNonQuery();
MessageBox.Show("Dato Aggiunto");
}
sqliteCon.Close();
1.1
SqlCommand cmdRD = new SqlCommand("SELECT ResItem AS RD FROM tSE JOIN tL ON tSE.idSE=tL.idL WHERE tL.Selection=1", sqliteCon);
var RD = cmdRD.ExecuteScalar();
var tot =pass;
using (cmdRD)
{
using (SqlDataReader reader = cmdRD.ExecuteReader())
{
while (reader.Read())
{
if(reader[0].ToString()==fail)
{
tot = fail;
break;
}
}
MessageBox.Show(tot);
}
}
i'm arrived to that(1.1) it works but i've to insert the TOT into RProva
Based on your question and comment I think you misunderstood ExecuteScalar:
ExecuteScalar executes the query, and returns the first column of the first row in the result set returned by the query. learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.executescalar
I dont know the Type of "RD" or "PASS", but the IF in your example (when using ExecuteScalar) seems OK. Else when you are using ExecuteReader you should use some kind of an loop to iterate through the Items. Like this:
string pass = "abc"; // guessing types and values
string fail = "failed";
string sqliteCon = "Data Source=(localdb)\\MSSQLLocalDB;Database=BooksDb";
using (SqlConnection connection = new SqlConnection(sqliteCon))
{
connection.Open();
var queryString = #"SELECT ResItem AS RD
FROM tSE
JOIN tL ON tSE.idSE = tL.idL
WHERE tL.Selection=1";
var values = new List<string>();
using (SqlCommand command = new SqlCommand(queryString, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader[0].ToString());
}
}
}
var queryInsert = #"INSERT INTO tSD (NomeItem,ResItemDet,DateStartDet,DateEndDet)
VALUES (#NI, #RProva, #DATESE, #DATEED)";
using (SqlCommand command2 = new SqlCommand(queryInsert, connection))
{
foreach(var value in values)
{
command2.Parameters.Clear();
if (value.Equals(pass))
{
command2.Parameters.AddWithValue("#RProva", value);
}
else
{
command2.Parameters.AddWithValue("#RProva", fail);
}
command2.ExecuteNonQuery();
}
}
}
Theres for sure a better way, but maybe this helps you out.
EDIT:
Here is how I would implement your code example:
using (SqlConnection sqliteCon = new SqlConnection(connection))
{
sqliteCon.Open();
var values = new List<string>();
var query = "SELECT ResItem AS RD FROM tSE JOIN tL ON tSE.idSE=tL.idL WHERE tL.Selection=1";
using (SqlCommand cmdRD = new SqlCommand(query, sqliteCon))
{
var RD = cmdRD.ExecuteScalar();
using (SqlDataReader reader = cmdRD.ExecuteReader())
{
while (reader.Read())
{
values.Add(reader[0].ToString());
}
}
}
int generatedId = 0;
var query2 = "INSERT INTO tSD(NomeItem,ResItemDet,DateStartDet,DateEndDet) OUTPUT inserted.Id VALUES (#NI,#RProva,#DATESE,#DATEED)";
using (SqlCommand cmd1 = new SqlCommand(query2, sqliteCon))
{
foreach (var value in values)
{
cmd1.Parameters.Clear();
cmd1.Parameters.AddWithValue("#DATESE", DATESE);
cmd1.Parameters.AddWithValue("#DATEED", DATEED);
cmd1.Parameters.AddWithValue("#NI", NI);
if (value.Equals(pass))
{
cmd1.Parameters.AddWithValue("#RProva", value);
}
else
{
cmd1.Parameters.AddWithValue("#RProva", fail);
}
cmd1.ExecuteNonQuery();
}
generatedId = Convert.ToInt32(cmd1.ExecuteScalar());
}
var query3 = "UPDATE tSE SET FK_TSD_id = #tsdId FROM tL JOIN tSE ON tL.idL = tSE.idSE WHERE tL.Selection=1 ";
using (SqlCommand cmd2 = new SqlCommand(query3, sqliteCon))
{
cmd2.Parameters.AddWithValue("#tsdId", generatedId);
cmd2.ExecuteNonQuery();
}
}

Exception: Invalid attempt to Read when reader is closed

I am trying to update my database while reading data from it, but the reader gets closed and it throws the exception that it can''t read wen reader is closed. Is the update.ExecuteNonQuery() closing the reader method?
If i get rid of linescon.Close(); con.Open(); i get There is already an open DataReader associated with this Connection which must be closed first.
So how can i update my database records while keep the reading opened?
{
public class MySqlReadUpdate
{
public int Id { get; set; }
public string Notes { get; set; }
}
static void Main()
{
List<MySqlReadUpdate> dbData = new List<MySqlReadUpdate>();
var config = "server=localhost;user id=root; database=restaurants; pooling=false;SslMode=none;Pooling=True";
MySqlConnection con = new MySqlConnection(config);
MySqlDataReader reader = null;
string query = "SELECT id, notes FROM customers";
MySqlCommand command = new MySqlCommand(query, con);
con.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
MySqlReadUpdate newMySqlReadUpdate = new MySqlReadUpdate();
newMySqlReadUpdate.Id = (int)reader["id"];
newMySqlReadUpdate.Notes = (string)reader["notes"];
string note = newMySqlReadUpdate.Notes;
var notesplit = note.Split(' ', '\n')[1];
dbData.Add(newMySqlReadUpdate);
Console.WriteLine(newMySqlReadUpdate.Id);
Console.WriteLine(newMySqlReadUpdate.Notes);
Console.WriteLine(note);
Console.WriteLine(notesplit);
con.Close();
con.Open();
string query2 = "UPDATE customers SET notes='" + notesplit + "' WHERE id='" + newMySqlReadUpdate.Id + "';";
MySqlCommand update = new MySqlCommand(query2, con);
update.ExecuteNonQuery();
}
con.Close();
Console.WriteLine("Finished!");
Console.Read();
}
}
}
You cannot close a connection like you are, because the data reader depends on it. Once you call con.Close you break it. That's why you see an exception the next time it gets to reader.Read().
What you want is to add MultipleActiveResultSets=True in the configuration string; however, as we discussed in the comments it's apparently still not supported in MySQL. Therefore, the answer is two connection instances.
List<MySqlReadUpdate> dbData = new List<MySqlReadUpdate>();
var config = "server=localhost;user id=root;database=restaurants;pooling=false;SslMode=none";
MySqlConnection con = new MySqlConnection(config);
MySqlConnection cmdCon = new MySqlConnection(config);
MySqlDataReader reader = null;
string query = "SELECT id, notes FROM customers";
MySqlCommand command = new MySqlCommand(query, con);
con.Open();
cmdCon.Open();
reader = command.ExecuteReader();
while (reader.Read())
{
MySqlReadUpdate newMySqlReadUpdate = new MySqlReadUpdate();
newMySqlReadUpdate.Id = (int)reader["id"];
newMySqlReadUpdate.Notes = (string)reader["notes"];
string note = newMySqlReadUpdate.Notes;
var notesplit = note.Split(' ', '\n')[1];
dbData.Add(newMySqlReadUpdate);
Console.WriteLine(newMySqlReadUpdate.Id);
Console.WriteLine(newMySqlReadUpdate.Notes);
Console.WriteLine(note);
Console.WriteLine(notesplit);
string query2 = "UPDATE customers SET notes='" + notesplit + "' WHERE id='" + newMySqlReadUpdate.Id + "';";
MySqlCommand update = new MySqlCommand(query2, cmdCon);
update.ExecuteNonQuery();
}
con.Close();
cmdCon.Close();
Console.WriteLine("Finished!");
Console.Read();
I would recommend that you also modify your code to use using statements or wrap things in try-finally blocks.

SQLite command construct WHERE clause

How to use Combobox.SelectedValue to construct WHERE clause?
conL.Open();
cmdL.Connection = conL;
cmdL.CommandText ="SELECT Id FROM dbAllServers WHERE Server_Names='" + cmb_SQLNames.SelectedValue +"'";
SQLiteDataReader r = cmdL.ExecuteReader();
while(r.Read())
{
serID = int.Parse(r[0].ToString());
MessageBox.Show("Current Selected Server ID is:..." + serID.ToString());
}
conL.Close();
An example of parameterized query, might be helpful:
string query = "SELECT Id FROM dbAllServers WHERE Server_Names=#server_name";
string serverName = cmb_SQLNames.SelectedValue;
using (SQLiteConnection connection = new SQLiteConnection(GetConnectionString()))
{
connection.Open();
using (var cmd = new SQLiteCommand(query, connection))
{
cmd.Parameters.Add(new SQLiteParameter("#server_name", serverName));
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
// do your job here
}
}
}
}

Object reference is not set to an instance Access query C#

I'm trying to make a query into the Clients table, when the user enters a mobile number, the code checks if it matches any record, if it does, it returns the client's Name & Address into text boxes, but I'm getting this error "Object reference is not set to an instance of an object" by the time I enter anything into that textbox
here is the code, what could be the problem?
private void textBox11_TextChanged(object sender, EventArgs e)
{
clientsearch();
clientsearch2();
}
public void clientsearch()
{
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
{
conn.Open();
string query = #"select Cname From Clients where Cmobile = #mobile";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
cmd.ExecuteNonQuery();
string result = cmd.ExecuteScalar().ToString();
textBox12.Text = #result;
}
}
public void clientsearch2()
{
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
{
conn.Open();
string query = #"select Caddress From Clients where Cmobile = #mobile";
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand(query, conn);
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
cmd.ExecuteNonQuery();
string result = cmd.ExecuteScalar().ToString();
textBox13.Text = #result;
}
}
string result = cmd.ExecuteScalar().ToString();
textBox12.Text = #result;
#result isn't anything. You just want result. Additionally, sending separate queries to the server for this data is pointlessly inefficient. Do this instead:
public void clientsearch()
{
string query = #"select Cname, Caddress From Clients where Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = textBox11.Text;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
if (rdr.Read())
{
textBox12.Text = rdr["Cname"].ToString();
textBox13.Text = rdr["Caddress"].ToString();
}
rdr.Close();
}
}
}
Finally, it's better style to also abstract your database code away from user interface. Ideally you would return a Client class, but since I don't see one I'll show an example using a tuple instead:
public Tuple<string, string> FindClientByMobile(string mobile)
{
string query = #"SELECT Cname, Caddress FROM Clients WHERE Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = mobile;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
return Tuple<string, string>.Create(rdr["Cname"].ToString(), rdr["Caddress"].ToString());
}
}
}
If you're playing with a Visual Studio 2017 release candidate, you can also use the new Tuple shortcuts:
public (string, string) FindClientByMobile(string mobile)
{
string query = #"SELECT Cname, Caddress FROM Clients WHERE Cmobile LIKE #mobile + '*'";
using (var conn = new System.Data.OleDb.OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data source=|DataDirectory|\\crepeDB.accdb;"))
using (var cmd = System.Data.OleDb.OleDbCommand(query, conn))
{
cmd.Parameters.Add("#mobile", System.Data.OleDb.OleDbType.Integer).Value = mobile;
conn.Open();
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
return (rdr["Cname"].ToString(), rdr["Caddress"].ToString());
}
}
}
And then use them like this:
private void textBox11_TextChanged(object sender, EventArgs e)
{
var result = FindClientByMobile(textBox11.Text);
textBox12.Text = result.Item1;
textBox13.Text = result.Item2;
}

Categories

Resources