Use more than one row in a select statment - c#

I have a select satement in C# and i was wondering if it is possible to use diaplay email and username in two diffrent label.
Below is the query:
SqlDataReader reader;
string sendMessage = "SELECT Email, username FROM aspnet_Membership WHERE UserId = #UserId";
using (SqlConnection myConnection = new SqlConnection(connectionString))
{
myConnection.Open();
SqlCommand myCommand = new SqlCommand(sendMessage, myConnection);
myCommand.Parameters.AddWithValue("#UserId", newUserId);
ArrayList emailArray = new ArrayList();
label1 = myCommand.ExecuteReader();
label2 = myCommand.ExecuteReader();
}
Thank you

Yes, of course, but you need to call just one time the ExecuteReader and then use the SqlDataReader returned to get the field values of the current record. (Of course the text returned by the reader should be assigned to the Text property of the label, not to the label itself)
string sendMessage = "SELECT Email, username FROM aspnet_Membership WHERE UserId = #UserId";
using (SqlConnection myConnection = new SqlConnection(connectionString))
using (SqlCommand myCommand = new SqlCommand(sendMessage, myConnection))
{
myConnection.Open();
myCommand.Parameters.AddWithValue("#UserId", newUserId);
using(SqlDataReader reader = myCommand.ExecuteReader())
{
while(reader.Read())
{
label1.Text = reader.GetString(reader.GetOrdinal("EMail"));
label2.Text = reader.GetString(reader.GetOrdinal("UserName"));
}
}
}
Also, do not forget to put the disposable objects like the command and the reader inside the appropriate using statement

Just call ExecuteReader once, and call Read method.Then you can get the values using indexer:
reader = myCommand.ExecuteReader();
reader.Read();
label1.Text = reader["Email"].ToString();
label2.Text = reader["username"].ToString();

Related

How to store multiple SQL data columns into different variables 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();
}
}
}

Display into textbox using if sentence

I'm displaying some data from the database into textboxes on my windows form and I have to add something else but it depends on the account type (that information is saved on my Databse). Meaning it is either DM (domestic) or CM(comercial). I want for it to charge an extra amount if it's CM.
I would appreciate any help, thank you.
OracleDataReader myReader = null;
OracleCommand myCommand = new OracleCommand("SELECT SUM(IMPORTE) AS corriente FROM MOVIMIENTOS WHERE CUENTA='"+txtIngreseCuenta3.Text + "'AND CONCEPTO=10", connectionString);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
txtCorriente.Text = (myReader["corriente"].ToString());
}
I'm using this code to display into the textbox but I want it to get the account type from another table and IF it's CM then add a certain amount into a textbox.
In your case I suggest that you use Execute Scalar instead of reader since you are returning only one value from the database. but in your case if you want this code to work you need to Cast the returned value into the correct dot net type and then populate the TextBox.
Example Using ExecuteReader
//txtCorriente.Text = ((int)myReader["corriente"]).ToString();
private static void CreateCommand(string queryString,
string connectionString)
{
using (SqlConnection connection = new SqlConnection(
connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
txtCorriente.Text = ((int)reader["corriente"]).ToString();
txtAnother.Text = ((decimal)reader["another"]).ToString();
Console.WriteLine(String.Format("{0}", reader[0]));
}
}
}
Example Using ExecuteScalar
static public int AddProductCategory(string newName, string connString)
{
Int32 newProdID = 0;
string sql =
"INSERT INTO Production.ProductCategory (Name) VALUES (#Name); "
+ "SELECT CAST(scope_identity() AS int)";
using (SqlConnection conn = new SqlConnection(connString))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add("#Name", SqlDbType.VarChar);
cmd.Parameters["#name"].Value = newName;
try
{
conn.Open();
newProdID = (Int32)cmd.ExecuteScalar();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
return (int)newProdID;
}

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"]);
}
}
}
}

"There is already an open DataReader associated with this Command which must be closed first."

I'm working on application which needs to connect to another database to get some data,
and to do that, I decided to use SqlConnection, reader etc..
And I need to execute few queries, for example first I need to get CARD ID for some user, after that I need to get some data by that CARD ID..
Here is my code:
#region Connection to another Database
SqlConnection sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=TestDatabase;Integrated Security=False; User ID=test; Password=test123;");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.CommandText = "Select * From Users Where CardID=" + "'" + user.CardID + "'";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
string cardID = "";
string quantity="";
while (reader.Read())
{
cardID = reader["CardID"].ToString();
}
//HOW COULD I WRITE ANOTHER QUERY NOW, FOR EXAMPLE, OK I GOT CARDID NOW GIVE ME SOME OTHER THINGS FROM THAT DATABASE BY THAT cardID
//here I tried to change CommandText and to keep working with reader.. but its not working like this because its throwing me exception mention in question title.
cmd.CommandText = "Select T1.CardID, T2.Title, Sum(T1.Quantity) as Quantity From CardTransactions as T1 JOIN Adds as T2 ON T1.AddsID = T2.AddsID Where T1.CardID =" + cardID + "AND T1.Type = 1 Group By T1.CardID, T2.Title";
reader = cmd.ExecuteReader();
while (reader.Read())
{
quantity = reader["Quantity"].ToString();
}
// Data is accessible through the DataReader object here.
sqlConnection1.Close();
#endregion
So guys how could I execute few queries statemens using this example.
Thanks a lot!
Cheers
Your problem is that you are not disposing the objects you are using. For that purpose is better to always use using structure, since it will guarantee you that everithing is gonna be disposed. Try the code below:
SqlConnection sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=TestDatabase;Integrated Security=False; User ID=test; Password=test123;");
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
string cardID = "";
string quantity="";
using(sqlConnection1 = new SqlConnection("Data Source=ComputerOne; Initial Catalog=TestDatabase;Integrated Security=False; User ID=test; Password=test123;"))
{
sqlConnection1.Open();
using(cmd = new SqlCommand())
{
cmd.CommandText = "Select * From Users Where CardID=" + "'" + user.CardID + "'";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
using(reader = cmd.ExecuteReader())
{
while (reader.Read())
{
cardID = reader["CardID"].ToString();
}
} //reader gets disposed right here
} //cmd gets disposed right here
using(cmd = new SqlCommand())
{
cmd.CommandText = "Select T1.CardID, T2.Title, Sum(T1.Quantity) as Quantity From CardTransactions as T1 JOIN Adds as T2 ON T1.AddsID = T2.AddsID Where T1.CardID =" + cardID + "AND T1.Type = 1 Group By T1.CardID, T2.Title";
cmd.CommandType = CommandType.Text;
cmd.Connection = sqlConnection1;
using(reader = cmd.ExecuteReader())
{
while (reader.Read())
{
quantity = reader["Quantity"].ToString();
}
} //reader gets disposed right here
} //cmd gets disposed right here
sqlConnection1.Close();
} //sqlConnection1 gets disposed right here
The reader you opened is still active and open. And you can have just one active reader at a time. You should wrap all Sql... instances in a using to ensure they get closed properly.
using (SqlConnection connection = new SqlConnection(...))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
// the code using reader
}
}
well ... you receive the error because the used reader for the first call was not closed. You should always call the Close method when you have finished using the DataReader object insuring that the connection used by the reader is returned to the connection pool (the connection is in use exclusively by that DataReader). Partial code:
reader = cmd.ExecuteReader();
try
{
while(myReader.Read())
{
while (reader.Read())
{
cardID = reader["CardID"].ToString();
}
}
finally
{
myReader.Close();
}
...
reader = cmd.ExecuteReader();
try
{
while(myReader.Read())
{
reader = cmd.ExecuteReader();
while (reader.Read())
{
quantity = reader["Quantity"].ToString();
}
}
}
finally
{
myReader.Close();
myConnection.Close();
}
Also... as a clean code rule, separate your calls in different methods (SOLID principles)

Get int value from command in c#

string sql = "Select UserId From User where UserName='Gheorghe'";
SqlCommand cmd=new SqlCommand(sql, connection);
cmd.ExecuteScalar(); //this statement return 0
but I want to get the id of user?
how can I get it?
You need the SqlDataReader.
SqlDataReader Provides a way of reading a forward-only stream of rows from a SQL Server database.
Sample
string sql = "Select UserId From User where UserName='Gheorghe'";
SqlCommand cmd=new SqlCommand(sql, connection);
SqlDataReader rd = cmd.ExecuteReader();
if (rd.HasRows) {
rd.Read(); // read first row
var userId = rd.GetInt32(0);
}
More Information
MSDN - SqlDataReader Class
Simply cast the returned value:
int userId = (Int32)cmd.ExecuteScalar();
But be aware that ExecuteScalar will return null if your query returns an empty result set, and in that case the above code snippet will throw an InvalidCastException.
try with select TOP 1 and ExecuteScalar
string sql = "Select TOP 1 UserId From User where UserName='Gheorghe'";
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
var result = (Int32)cmd.ExecuteScalar();
}
}

Categories

Resources