How to store multiple SQL data columns into different variables C# - c#

I am trying to store sql data that I have for a voucher id and voucher amount into a variable and display it into a label on a click of a button.
protected void Button1_Click(object sender, EventArgs e)
{
string voucherId = String.Empty;
string voucherAmount = String.Empty;
string queryVoucherId = "select voucherid from ReturnForm where email = '" + Session["username"] + "';";
string queryVoucherAmount = "select voucheramount from ReturnForm where email = '" + Session["username"] + "';";
int index = 0;
using (SqlConnection con = new SqlConnection(str))
{
SqlCommand cmd = new SqlCommand(queryVoucherId, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
voucherId = reader[index].ToString();
index++;
}
}
using (SqlConnection con = new SqlConnection(str))
{
SqlCommand cmd = new SqlCommand(queryVoucherAmount, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
voucherAmount = reader[index].ToString();
index++;
}
}
if (txtVoucher.Text == voucherId)
{
Label3.Visible = true;
Label3.Text = voucherAmount;
}
}
When I click the button its giving me an error saying that the index is out of bounds.

Building on #JSGarcia's answer - but using parameters as one ALWAYS should - you'd get this code:
string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom WHERE Email = #email";
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(query, conn))
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
// set the parameter before opening connection
// this also defines the type and length of parameter - just a guess here, might need to change this
cmd.Parameters.Add("#email", SqlDbType.VarChar, 100).Value = email;
conn.Open();
sda.Fill(dt);
conn.Close();
}
Personally, I'd rather use a data class like
public class VoucherData
{
public int Id { get; set; }
public Decimal Amount { get; set; }
}
and then get back a List<VoucherData> from your SQL query (using e.g. Dapper):
string query = $"SELECT Id, Amount FROM ReturnFrom WHERE Email = #email";
List<VoucherData> vouchers = conn.Query<VoucherData>(query).ToList();
I'd try to avoid the rather clunky and not very easy to use DataTable construct...

I strongly recommend combining your sql queries into a single one, write it into a datatable and continue your logic from there. IMHO it is much cleaner code:
string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom where Email = '{email}'";
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = conn.CreateCommand())
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
conn.Open();
sda.Fill(dt);
conn.Close();
}
// Work with DataTable dt from here on
...

Well, one more big tip?
You ONLY as a general rule need a dataadaptor if you going to update the data table.
And you ONLY need a new connection object if you say not using the sql command object.
The sqlcommand object has:
a connection object - no need to create a separate one
a reader - no need to create a separate one.
Note how I did NOT create a seperate connection object, but used the one built into the command object.
And since the parameter is the SAME in both cases? Then why not re-use that too!!
So, we get this:
void TestFun2()
{
String str = "some conneciton???";
DataTable rstVouch = new DataTable();
using (SqlCommand cmdSQL =
new SqlCommand("select voucherid from ReturnForm where email = #email",
new SqlConnection(str)))
{
cmdSQL.Parameters.Add("#email", SqlDbType.NVarChar).Value = Session["username"];
cmdSQL.Connection.Open();
rstVouch.Load(cmdSQL.ExecuteReader());
// now get vouch amount
cmdSQL.CommandText = "select voucheramount from ReturnForm where email = #email";
DataTable rstVouchAmount = new DataTable();
rstVouchAmount.Load(cmdSQL.ExecuteReader());
if (rstVouch.Rows[0]["vourcherid"].ToString() == txtVoucher.Text)
{
Label3.Visible = true;
Label3.Text = rstVouchAmount.Rows[0]["voucheramount"].ToString();
}
}
}

Related

Issues with autofilling checkboxes

Could I use a read only collection here and drop the dataset? I am new to C# and I am stumped at how to do this. I have a dropdown-box that is being filled from a column in SQL that holds client names. I have a text-box that you enter an email address into that will update the email address in SQL with the values checked in the dropdown-box. Now when the email is entered into the textbox is there a way I can pull these saved values from SQL and have the checkboxes "auto" checked based on what is already in the table for the corresponding email? I have seen this done with coded values but not values from SQL. Also if an email has access to more than 1 client, the client names are pipe delimited when inserted into SQL.
Here Is what I have so far.
if (EmailList.Value == "") Connection ls = new Connection(); Recordset rs = new Recordset();
ls.Open(connections.myconn);
rs.Open("select email from users order by email", ls);
string emails = "";
while (!rs.EOF) { emails += rs.Fields[0].Value + " "; rs.MoveNext(); }
EmailList.Value = emails;
using (SqlCommand cmd1 = new SqlCommand("SELECT * FROM tracking_mpc order by ClientName"))
{
cmd1.CommandType = CommandType.Text;
cmd1.Connection = con1;
con1.Open();
webreport.DataSource = cmd1.ExecuteReader();
webreport.DataTextField = "ClientName";
webreport.DataValueField = "CltID";
webreport.DataBind();
con1.Close();
}
public string StringFromDatabase()
{
try
{
var dataSet = new DataSet();
string constr=ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
using (SqlConnection myConnect = new SqlConnection(constr))
myConnect.Open();
var command = new SqlCommand("SELECT Clients from users WHERE Email =" + EmailTextBox.Text)
{
CommandType = CommandType.StoredProcedure
};
var dataAdapter = new SqlDataAdapter { SelectCommand = command };
dataAdapter.Fill(dataSet);
return dataSet.Tables[0].Rows[0]["Clients"].ToString();
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
Here is a better implementation of your StringFromDatabase:
public List<string> GetClientNames(string email)
{
var constr=ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
var sql = "SELECT Clients FROM users WHERE Email=#email";
using (var conn = new SqlConnection(constr))
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add("#email",SqlDbType.VarChar).Value = email;
conn.Open();
return ((string)cmd.ExecuteScalar()).Split('|').ToList();
}
}
Here is the same, but in a database agnostic way (works if you change your connection string to say MySql, Oracle, etc):
public List<string> GetClientNames(string email)
{
var constr = ConfigurationManager.ConnectionStrings["myConnectionString"];
var sql = "SELECT Clients FROM users WHERE Email=#email";
var factory = DbProviderFactories.GetFactory(constr.ProviderName);
using (var conn = factory.CreateConnection())
using (var cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
conn.ConnectionString = constr.ConnectionString;
var param = cmd.CreateParameter();
param.ParameterName = "#email";
param.Value = email;
cmd.Parameters.Add(param);
conn.Open();
return ((string)cmd.ExecuteScalar()).Split('|').ToList();
}
}

Problem with query string and extract values

I can't extract the values through a query and insert them into textboxes
Where am I going wrong?
Request.QueryString.Get("ID_Persona");
string query = "SELECT ID,Nome,Cognome,Email,CodiceFiscale FROM Persona WHERE ID = #id";
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString))
{
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("#ID","");
cmd.Parameters.AddWithValue("#Nome", TextBox1.Text);
cmd.Parameters.AddWithValue("#Cognome", TextBox15.Text);
cmd.Parameters.AddWithValue("#Email", TextBox20.Text);
cmd.Parameters.AddWithValue("#CodiceFiscale", TextBox22.Text);
con.Open();
cmd.ExecuteNonQuery();
}
You need to use ExecuteReader to read values, something like this:
var connectionString = ConfigurationManager.ConnectionStrings["dbConnection"].ConnectionString;
string query = "SELECT ID,Nome,Cognome,Email,CodiceFiscale FROM Persona WHERE ID = #id";
using (SqlConnection con = new SqlConnection(connectionString))
{
using (var cmd = new SqlCommand(query, con))
{
cmd.Parameters.AddWithValue("#ID", Request.QueryString.Get("ID_Persona"));
con.Open();
using (var rdr = cmd.ExecuteReader())
{
if (rdr.Read())
{
//IDTextBox? = rdr["Id"].ToString(),
TextBox1.Text = rdr["Nome"].ToString(),
TextBox15.Text = rdr["Cognome"].ToString(),
TextBox20.Text= rdr["Email"].ToString(),
TextBox22.Text= rdr["CodiceFiscale"].ToString(),
}
}
}
}
You should use a ExecuteReader() instead of ExecuteNonQuery() since ExecuteNonQuery is meant for DML operations. Again, you need only the ID value to be passed then why you are passing unnecessary parameters to your query. Remove them all. An example below
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine(String.Format("{0}", reader["Email"]));
}
I can see several issues:
You should use ExecuteReader() instead of ExecuteNonQuery()
You should provide just 1 parameter - #ID; I doubt if it should have an empty value.
You should wrap IDisposable into using
Code:
string query =
#"SELECT ID,
Nome,
Cognome,
Email,
CodiceFiscale
FROM Persona
WHERE ID = #id";
using (SqlConnection con = new SqlConnection(...))
{
con.Open();
using SqlCommand cmd = new SqlCommand(query, con)
{
// I doubt if you want empty Id here.
// I've assumed you want to pass ID_Persona
cmd.Parameters.AddWithValue("#ID", Request.QueryString.Get("ID_Persona"));
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
TextBox1.Text = Convert.ToString(reader["Nome"]);
TextBox15.Text = Convert.ToString(reader["Cognome"]);
TextBox20.Text = Convert.ToString(reader["Email"]);
TextBox22.Text = Convert.ToString(reader["CodiceFiscale"]);
}
}
}
}

WebService only returning first row using a sql queryC#

I have the following code
public class dthvendas: System.Web.Services.WebService {
public class typVenda
{
//public string campanha;
public string id;
public string contact_moment;
public string nome;
// few more properties
}
[WebMethod][SoapDocumentMethod]
public typVenda getListaVendas(string dt_min, string dt_max)
{
//venda vendas = new List<venda>();
typVenda objVenda = new typVenda();
SqlConnection con = new SqlConnection(#"Data Source=server;Initial Catalog=database;User ID=user;password=password");
//SqlCommand cmd = new SqlCommand("SELECT * FROM dbo where contact_moment >='" + dt_min + "' AND contact_moment <DATEADD(dd, 1, '" + dt_max + "')", con);
SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.vcnosadesoes_getlistavendas", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
//var objVenda = new typVenda();
//objVenda.campanha = dr["id"].ToString();
objVenda.id = dr["id"].ToString();
objVenda.contact_moment = dr["contact_moment"].ToString();
objVenda.nome = dr["nome"].ToString();
objVenda.pacote = dr["pacote"].ToString();
objVenda.telefone = dr["telefone"].ToString();
objVenda.codigo_wc = dr["codigo_wc"].ToString();
//vendas.Add(objVenda);
}
dr.Close();
}
con.Close();
return objVenda;
//return vendas.ToArray();
}
The problem is that is only returning the first row instead of all rows from the table. What could be the problem any ideas?
Also when i return it says "This XML file does not appear to have any style information associated with it. The document tree is shown below." It should have a header like this:
<?xml version="1.0" encoding="UTF‐8" ?>
If you have n fetched rows available in the reader, probably you will get the last row, since the created object's properties ware over writted in each iteration of the while (dr.Read()) and finally return the latest value to the calling method. You should re-define your method to return List<typVenda>, and hence populate the list with objects constructed in each iteration. and finally return the list at the end of iteration.
Few more suggestions For you to improve the Code:
Make use of using while dealing with SqlConnection and SqlCommand; since you need not to bother about the close connection and disposing commands etc. using will take care of these things
Need not to check the reader has rows or not (if (dr.HasRows)) use while (dr.Read()) will not execute the enclosed statements if there are no rows.
Now consider the following code:
public List<typVenda> getListaVendas(string dt_min, string dt_max)
{
List<typVenda> objVendaList = new List<typVenda>();
using (SqlConnection con = new SqlConnection("connection String here"))
{
using (SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.vcnosadesoes_getlistavendas", con))
{
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
var objVenda = new typVenda();
// Assign the values to the properties here
objVendaList.Add(objVenda);
}
dr.Close();
}
}
return objVendaList;
}
public List<typVenda> getListaVendas(string dt_min, string dt_max)
{
venda vendas = new List<typVenda>();
typVenda objVenda = new typVenda();
SqlConnection con = new SqlConnection(#"Data Source=server;Initial Catalog=database;User ID=user;password=password");
//SqlCommand cmd = new SqlCommand("SELECT * FROM dbo where contact_moment >='" + dt_min + "' AND contact_moment <DATEADD(dd, 1, '" + dt_max + "')", con);
SqlCommand cmd = new SqlCommand("SELECT * FROM dbo.vcnosadesoes_getlistavendas", con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
var objVenda = new typVenda();
//objVenda.campanha = dr["id"].ToString();
objVenda.id = dr["id"].ToString();
objVenda.contact_moment = dr["contact_moment"].ToString();
objVenda.nome = dr["nome"].ToString();
objVenda.pacote = dr["pacote"].ToString();
objVenda.telefone = dr["telefone"].ToString();
objVenda.codigo_wc = dr["codigo_wc"].ToString();
vendas.Add(objVenda);
}
dr.Close();
}
con.Close();
return vendas;
}

how two get data from 2 different table c#

I have two table.I need to get calorificValue from the food table and daily_gained from the calorie_tracker table to then make some calculations.I've written this code, I know it not efficent. It retrieves daily_gained but failed to get calorificValue.
MySqlCommand cmd = new MySqlCommand("SELECT name,calorificValue FROM myfitsecret.food where name=#name", cnn);
MySqlCommand cmd2 = new MySqlCommand("SELECT sportsman_id,daily_gained FROM myfitsecret.calorie_tracker where sportsman_id=#sportsman_id", cnn);
cmd2.Parameters.AddWithValue("#sportsman_id", Login.userID);
string s = (comboBox1.SelectedItem).ToString();
cmd.Parameters.AddWithValue("#name",s);
cmd2.Connection.Open();
MySqlDataReader rd = cmd2.ExecuteReader(CommandBehavior.CloseConnection);
int burned = 0;
if (rd.HasRows) // if entered username and password have the data
{
while (rd.Read()) // while the reader can read
{
if (rd["sportsman_id"].ToString() == Login.userID) // True for admin
{
burned += int.Parse(rd["daily_gained"].ToString());
}
}
}
cmd2.Connection.Close();
cmd.Connection.Open();
MySqlDataReader rd2 = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (rd2.HasRows) // if entered username and password have data
{
while (rd2.Read()) // while the reader can read
{
if (rd2["name"].ToString() == s)
{
burned += int.Parse(rd2["calorificValue"].ToString());
}
}
}
MessageBox.Show(burned+"");
DataTable tablo = new DataTable();
string showTable = "SELECT * from myfitsecret.calorie_tracker where sportsman_id=#sportsman_id";
MySqlDataAdapter adapter = new MySqlDataAdapter();
MySqlCommand showCommand = new MySqlCommand();
showCommand.Connection = cnn;
showCommand.CommandText = showTable;
showCommand.CommandType = CommandType.Text;
showCommand.Parameters.AddWithValue("#sportsman_id", Login.userID);
adapter.SelectCommand = showCommand;
adapter.Fill(tablo);
dataGridView1.DataSource = tablo;
cnn.Close();
Why don't you just use the scalar function SUM and let the database do its job instead of writing a lot of code?
int burned = 0;
string s = comboBox1.SelectedItem.ToString();
cnn.Open();
string cmdText = #"SELECT SUM(calorificValue)
FROM myfitsecret.food
WHERE name=#name";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = s;
object result = cmd.ExecuteScalar();
burned += (result != null ? Convert.ToInt32(result) : 0);
}
cmdText = #"SELECT SUM(daily_gained)
FROM myfitsecret.calorie_tracker
WHERE sportsman_id=#sportsman_id";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
cmd.Parameters.Add("#sportsman_id", MySqlDbType.Int32).Value = Login.userID;
object result = cmd.ExecuteScalar();
burned += (result != null ? Convert.ToInt32(result) : 0);
}
Not visible from your code, but also the connection should be created inside a using statement (very important with MySql that is very restrictive with simultaneous open connections)
We could also use a different approach putting the two commands together and separating them with a semicolon. This is called batch commands and they are both executed with just one trip to the database. Of course we need to fallback using the MySqlDataReader to get the two results passing from the first one to the second one using the NextResult() method (see here MSDN for Sql Server)
string cmdText = #"SELECT SUM(calorificValue)
FROM myfitsecret.food
WHERE name=#name;
SELECT SUM(daily_gained)
FROM myfitsecret.calorie_tracker
WHERE sportsman_id=#sportsman_id";
using(MySqlCommand cmd = new MySqlCommand(cmdText, cnn))
{
// Add both parameters to the same command
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = s;
cmd.Parameters.Add("#sportsman_id", MySqlDbType.Int32).Value = Login.userID;
cnn.Open();
using(MySqlDataReader reader = cmd.ExecuteReader())
{
// get sum from the first result
if(reader.Read()) burned += Convert.ToInt32(reader[0]);
// if there is a second resultset, go there
if(reader.NextResult())
if(reader.Read())
burned += Convert.ToInt32(reader[0]);
}
}
Your issues could be around closing a connection and then trying to open it again. Either way it's fairly inefficient to be closing and opening connections.
MySqlCommand cmd = new MySqlCommand("SELECT name,calorificValue FROM myfitsecret.food where name=#name", cnn);
string s = (comboBox1.SelectedItem).ToString();
cmd.Parameters.AddWithValue("#name",s);
MySqlCommand cmd2 = new MySqlCommand("SELECT SUM(daily_gained) FROM myfitsecret.calorie_tracker where sportsman_id=#sportsman_id", cnn);
cmd2.Parameters.AddWithValue("#sportsman_id", Login.userID);
cnn.Open();
MySqlDataReader rd = cmd.ExecuteReader();
if (rd.HasRows) // if entered username and password have data
{
while (rd.Read()) // while the reader can read
{
burned += int.Parse(rd["calorificValue"].ToString());
}
}
burned = cmd2.ExecuteScalar();
MessageBox.Show(burned+"");
cnn.Close();

insert data to table based on another table C#

I wrote some code that takes some values from one table and inserts the other table with these values.(not just these values, but also these values(this values=values from the based on table))
and I get this error:
System.Data.OleDb.OleDbException (0x80040E10): value wan't given for one or more of the required parameters.`
here's the code. I don't know what i've missed.
string selectedItem = comboBox1.SelectedItem.ToString();
Codons cdn = new Codons(selectedItem);
string codon1;
int index;
if (this.i != this.counter)
{
//take from the DataBase the matching codonsCodon1 to codonsFullName
codon1 = cdn.GetCodon1();
//take the serialnumber of the last protein
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=C:\\Projects_2012\\Project_Noam\\Access\\myProject.accdb";
OleDbConnection conn = new OleDbConnection(connectionString);
conn.Open();
string last= "SELECT proInfoSerialNum FROM tblProInfo WHERE proInfoScienceName = "+this.name ;
OleDbCommand getSerial = new OleDbCommand(last, conn);
OleDbDataReader dr = getSerial.ExecuteReader();
dr.Read();
index = dr.GetInt32(0);
//add the amino acid to tblOrderAA
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
string insertCommand = "INSERT INTO tblOrderAA(orderAASerialPro, orderAACodon1) "
+ " values (?, ?)";
using (OleDbCommand command = new OleDbCommand(insertCommand, connection))
{
connection.Open();
command.Parameters.AddWithValue("orderAASerialPro", index);
command.Parameters.AddWithValue("orderAACodon1", codon1);
command.ExecuteNonQuery();
}
}
}
EDIT:I put a messagebox after that line:
index = dr.GetInt32(0);
to see where is the problem, and I get the error before that. I don't see the messagebox
Your SELECT Command has a syntax error in it because you didn't enclose it with quotes.
Change this:
string last = "SELECT proInfoSerialNum FROM tblProInfo WHERE proInfoScienceName = "+this.name ;
OleDbCommand getSerial = new OleDbCommand(last, conn);
OleDbDataReader dr = getSerial.ExecuteReader();
to
string last = "SELECT proInfoSerialNum FROM tblProInfo WHERE proInfoScienceName = ?";
OleDbCommand getSerial = new OleDbCommand(last, conn);
getSerial.Parameters.AddWithValue("?", this.name);
OleDbDataReader dr = getSerial.ExecuteReader();
This code is example from here:
string SqlString = "Insert Into Contacts (FirstName, LastName) Values (?,?)";
using (OleDbConnection conn = new OleDbConnection(ConnString))
{
using (OleDbCommand cmd = new OleDbCommand(SqlString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("FirstName", txtFirstName.Text);
cmd.Parameters.AddWithValue("LastName", txtLastName.Text);
conn.Open();
cmd.ExecuteNonQuery();
}
}
Try to do the same as in the example.

Categories

Resources