getting values from sql reader c# - c#

I have the following code:
SqlConnection c = new SqlConnection("Data Source=localhost\\sqlexpress;Initial Catalog=BookStoreDataBase1;Integrated Security=True;Pooling=False;");
c.Open();
string raf = string.Format("Select Id from Customer WHERE email='{0}'", DropDownList1.SelectedItem.Text);
SqlCommand comm2 = new SqlCommand(raf, c);
SqlDataReader r = comm2.ExecuteReader();
The object r now has the value of the query which is a row contains that the Id where email equals to random value from drop down list.
what I want is to get the exact value of that "Id" and assign it to label. please help me.

First of all your query is open to SQL Injection attack so change it like this:-
string raf = "Select Id from Customer WHERE email= #Email";
SqlCommand comm2 = new SqlCommand(raf, c);
cmoo2.Parameters.Add("#Email",SqlDbType.NVarchar,20).Value =
DropDownList1.SelectedItem.Text;
You are fetching just one value so it can be done use ExecuteScalar like this:-
labelid.Text= cmoo2.ExecuteScalar.ToString();
But If you want to use SqlDataReader object then it will return the value when you call the Read method:-
using(SqlDataReader reader= cmoo2.ExecuteReader())
{
while (reader.Read())
{
labelid.Text= reader["Id"].ToString();
}
}

There are lot of examples already in stack overflow regarding this topic you can refer any of that answers or try this
using(SqlDataReader r= cmd.ExecuteReader())
{
while (r.Read())
{
var myString = r.GetString(0); //The 0 stands for "the 0'th column", so the first column of the result.
labelid.Text=myString;
}
}

Related

Get minimum value from columns in SQL Server using C# & ASP.NET

I'm trying to find the minimum value in "position" column. Here is my code:
public void minrank()
{
SqlConnection con1 = new SqlConnection(DecryptString(System.Configuration.ConfigurationManager.AppSettings["cn"], EncryptionKey2));
con1.Open();
string str1 = "select EmailAcmd5hash,eviewdate,MIN(eposition) from rankdata where EmailAcmd5hash=#EmailAcmd5hash and eviewdate=#eviewdate";
SqlCommand cmd1 = new SqlCommand(str1, con1);
cmd1.Parameters.AddWithValue("#EmailAcmd5hash", Request.Cookies["li"]["Ac"].ToString());
cmd1.Parameters.AddWithValue("#eviewdate", DateTime.Now.ToString("dd-MM-yyyy"));
SqlDataReader reader1 = cmd1.ExecuteReader();
if (reader1.HasRows)
{
topminranklbl.Text = (reader1["eposition"].ToString());
}
}
I'm getting this error:
Column 'rankdata.EmailAcmd5hash' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Please help me to solve this issue. Thanks in advance.
Change query to
select MIN(eposition) as eposition
from rankdata
where EmailAcmd5hash=#EmailAcmd5hash and eviewdate=#eviewdate
you should add EmailAcmd5hash and eviewdate columns to group by
string str1 = "select EmailAcmd5hash,eviewdate,MIN(eposition) eposition from rankdata where EmailAcmd5hash=#EmailAcmd5hash and eviewdate=#eviewdate group by EmailAcmd5hash,eviewdate";
or remove from select
string str1 = "select MIN(eposition) eposition from rankdata where EmailAcmd5hash=#EmailAcmd5hash and eviewdate=#eviewdate";
just refer to the parameter
string str1 = "select #EmailAcmd5hash, #eviewdate, MIN(eposition) from rankdata where EmailAcmd5hash = #EmailAcmd5hash and eviewdate = #eviewdate";

Invalid column error in SQL Server using "Where" condition

I'm doing a small program in C#, and I get the "invalid column name" error using the reader, although my column name exists. I looked for previous answers on StackOverflow, but didn't really understand the answers given.. Can someone explains me :
Why it bugs ?
How to solve this problem ?
Here is my code.
[HttpGet]
[Route("IP/{Station=0}/{Timestp=0}")]
public ActionResult IP(int station, string timestp)
{
timestp = timestp.Replace("_", ":");
SqlConnection myConn = new SqlConnection(#"Server=(LocalDb)\MSSqlLocalDB;Integrated security=SSPI;database=Serene7_Default_v1");
List<string> listeIps = new List<string>();
string listDb = string.Format("SELECT DISTINCT IdSource FROM [Serene5_Default_v1].[tcpdump].[TCPDump] WHERE Station = '{0}' AND TimeStp = '{1}';",station,timestp);
SqlCommand myCommand = new SqlCommand(listDb, myConn);
string listDb2 = string.Format("SELECT DISTINCT IdSource,IdDestination FROM [Serene5_Default_v1].[tcpdump].[TCPDump] WHERE Station = {0} AND TimeStp = '{1}';", station, timestp);
SqlCommand myCommand2 = new SqlCommand(listDb2, myConn);
myConn.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Serene7_Default_v1.INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TCPDump';", myConn);
//opens connection
SqlDataReader reader5 = cmd.ExecuteReader();
while (reader5.Read())
{
System.Diagnostics.Debug.WriteLine(reader5[3]);
// read 'name' column
}
reader5.Close();
SqlDataReader reader = myCommand.ExecuteReader();
while (reader.Read())
{
listeIps.Add(reader[0].ToString());
}
reader.Close();
// some stuff
return View(MVC.Views.Common.Dashboard.DashboardIndex, dashboard);
}
The reader5 returns :
IdTransmission
TimeStp
IdSource
IdDestination
PortSource
PortDestination
Protocol
ToTheRight
ToTheLeft
Station
and the error is :
Invalid column name 'Station'
Select query runs on [Serene5_Default_v1] DB, but you list table columns from [Serene7_Default_v1] DB. The table's schema in this two different DB equal?
Remove () around column list:
SELECT DISTINCT (IdSource,IdDestination)
=>
SELECT DISTINCT IdSource,IdDestination
DISTINCT can accept () only for one column.
Rextester Demo
Second thing:
string.Format("SELECT DISTINCT (IdSource,IdDestination) FROM [Serene5_Default_v1].[tcpdump].[TCPDump] WHERE Station = {0} AND TimeStp = '{1}';", station, timestp);
using string.Format could lead to SQL Injection attack. I strongly suggest to use parametrized query instead.
More info: Parameterized Queries

sql query to show data from price between two columns C#

EDIT: I am not able to format my code below, if any one can fix it.
I am new to sql queries and still learning.
Table Name: CommissionSetupTable.
I want to display #Paisa if gross_amount is between the range of #FromRate and #ToRate
Below is my code:
string paisa;
private void load_commission_setup()
{
SqlCeConnection conn = null;
SqlCeCommand cmd = null;
SqlCeDataReader rdr = null;
try
{
conn =
new SqlCeConnection(
#"Data Source=|DataDirectory|\Database.sdf;Persist Security Info=False");
conn.Open();
int rowindex = purchaseBillTableDataGridView.Rows.Count - 1;
gross_amount = double.Parse(purchaseBillTableDataGridView[10, rowindex].Value.ToString());
// Gross Amount is between the ranges of FromRate and ToRate.
cmd = new SqlCeCommand("SELECT Paisa FROM CommissionSetupTable WHERE='" + gross_amount.ToString() + "' BETWEEN #FromRate AND #ToRate;", conn);
rdr = cmd.ExecuteReader();
if (rdr == null)
{
}
else
{
while (rdr.Read())
{
paisa = rdr["Paisa"].ToString();
}
rdr.Close();
cmd.Dispose();
}
}
finally
{
conn.Close();
int rowindex = purchaseBillTableDataGridView.Rows.Count - 1;
purchaseBillTableDataGridView[11, rowindex].Value = paisa;
}
}
The correct syntax to use here is the following
cmd = new SqlCeCommand(#"SELECT Paisa FROM CommissionSetupTable
WHERE #gross BETWEEN FromRate AND ToRate;", conn);
Notice that the two field names should not be prefixed with #, otherwise they will be considered parameters placeholders.
And now, before executing the command, add the parameter for the #gross placeholder
cmd.Parameters.Add("#gross", SqlDbType.Decimal).Value = gross_amount;
I don't know what is the exact datatype of the columns FromRate and EndRate, but
note that you should use the correct datatype for your parameter. Do not pass a string and expect the database engine do the conversion for you. (or worse concatenate your value to the rest of the sql using ToString()). This is always wrong also if sometime the database engine could understand your values.
EDIT
Also, following your comments below, it appears that this line is wrong
int rowindex = purchaseBillTableDataGridView.Rows.Count - 1;
If your DataGridView has the property AllowUserToAddRow set to True then you want to use
int rowindex = purchaseBillTableDataGridView.Rows.Count - 2;
because the first line points to the empty row added to the DataGridView for inserting a new record.

Auto generate and AutoIncrement ID in C# when trying to add new record to database

I'm using this code to select the maxID from a database table and each time I want to add a new record, the autogenerated ID is not the last one +1.
public formularAddCompanie()
{
InitializeComponent();
try
{
string cs = "Data Source=CODRINMA\\CODRINMA;Initial Catalog=TrafficManager;Integrated Security=True";
string select = "SELECT max(IDCompanie) FROM Companii";
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlCommand cmd2 = new SqlCommand(select, con);
SqlDataReader sda = cmd2.ExecuteReader();
DataTable idmax = new DataTable("idmax");
idmax.Load(sda);
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else { txtID.Text = (int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
}
}
catch (Exception er) { MessageBox.Show(er.Message); }
}
The table from where the selection is made, looks like this:
IDCompany Name Address City RegNo
1 A Street NY 123
Each time I want to add a new record, the autogenerated ID is like this: 11, 111, 1111. It takes the last ID and add another 1 next to it. What am I missing?
Interestingly, note that
string a = "The meaning of life is " + 42;
converts 42 to a string, creating the result
a == "The meaning of life is 42"
Look at this code:
(int.Parse(idmax.Rows[0][0] .ToString() + 1).ToString()); }
You are converting idmax.Rows[0][0] to a string and adding +1 to the end of the string rather than to an integer value. Try
(int.Parse(idmax.Rows[0][0].ToString()) + 1).ToString(); }
Note that idmax.Rows[0][0] should already have an integer in it (as pointed out in the comments). If that's the case, you can simplify to
(idmax.Rows[0][0] + 1).ToString(); }
idmax.Rows[0][0].ToString() + 1 produces string, not int.
You can try
txtID.Text = (Convert.ToInt32(idmax.Rows[0][0]) + 1).ToString();
I just add this because it seems that none cares about the weakness of the code posted by the poster.
First the MAX function is not reliable if you want to find the next autoincrement value that will be assigned to an ID column. Concurrency could wreak havoc with any schema that use MAX. Just suppose that another user has already retrieved the MAX for its own INSERT operation, then depending on the relative speed of the two computers you or the other user will insert a duplicate value for the IDCompany field.
The only correct way to do this common task is to use the IDENTITY property for the column IDCompany and when you need to insert a new record you should write something like this
try
{
string insert = "INSERT INTO Companii (Name,Address,City,RegNo)
VALUES(#name,#address,#city,#regno);
SELECT SCOPE_IDENTITY()";
using (SqlConnection con = new SqlConnection(cs))
using (SqlCommand cmd = new SqlCommand(insert, con))
{
con.Open();
cmd.Parameters.Add("#name", SqlDbType.NVarChar).Value = txtBoxCity.Text;
.... and on for the other parameters ....
int companyID = Convert.ToInt32(cmd.ExecuteScalar());
... work with the just added company if required
}
}
catch (Exception er)
{ MessageBox.Show(er.Message); }
SCOPE_IDENTITY will return the last identity value inserted into an identity column in the same scope and in this context scope means the connection used by your command.
In any case, if the MAX approach is still required then the code could be simplified a lot using a modified query and SqlCommand.ExecuteScalar instead of building an SqlDataReader, filling a datatable, trying to parse the result with ifs
string getMax = #"select COALESCE(MAX(IDCompany), 0) + 1 AS maxPlusOne
from Companii"
using(SqlConnection cnn = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(getMax, cnn))
{
cnn.Open();
int nextCompanyID = Convert.ToInt32(cmd.ExecuteScalar());
}
The COALESCE function checks the result of the MAX function and if it is NULL returns the second parameter (here 0), then just increment by 1 to get the next MAX directly from the database. ExecuteScalar will do the call returning just the maxPlusOne alias field
try this snippet:
Convert Your String into Int. String with + operator will con-cat and with int it will add numbers.
if (idmax.Rows[0][0].ToString().Trim() == "") { txtID.Text = "1"; }
else {
txtID.Text = Convert.ToString(Convert.ToInt32(idmax.Rows[0][0] .ToString())+1); }
Try This one, my id format is USR001.The code will generate auto id based on the last id inside the database. If the last id in the database is USR001, the the code will generate USR002 and put the id to the textbox
con.Open();
string sqlQuery = "SELECT TOP 1 kode_user from USERADM order by kode_user desc";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
string input = dr["kode_user"].ToString();
string angka = input.Substring(input.Length - Math.Min(3, input.Length));
int number = Convert.ToInt32(angka);
number += 1;
string str = number.ToString("D3");
txtKodeUser.Text = "USR" + str;
}
con.Close();

oledbException was unhandled error appering

I'm trying to populate a text box with a forename and surname using the code below:
using (OleDbConnection connName = new OleDbConnection(strCon))
{
String sqlName = "SELECT forename, Surname FROM customer WHERE [customerID]=" + txtCustomerID.Text;
// Create a command to use to call the database.
OleDbCommand commandname = new OleDbCommand(sqlName, connName);
connName.Open();
// Create a reader containing the results
using (OleDbDataReader readerName = commandname.ExecuteReader())
{
readerName.Read(); // Advance to the first row.
txtName.Text = readerName[0].ToString();
}
connName.Close();
}
However I'm getting the error: OleDbException was unhandled.
"no required values for one of more required parameters"
at the ExecuteReader and I'm not sure how to go about fixing this.
EDIT: this code below is nearly the exact same bar for the information in the query but this exception is not coming up for it.
string strCon = Properties.Settings.Default.PID2dbConnectionString;
using (OleDbConnection conn = new OleDbConnection(strCon))
{
String sqlPoints = "SELECT points FROM customer WHERE [customerID]=" + txtCustomerID.Text;
conn.Open();
// Create a command to use to call the database.
OleDbCommand command = new OleDbCommand(sqlPoints, conn);
// Create a reader containing the results
using (OleDbDataReader reader = command.ExecuteReader())
{
reader.Read(); // Advance to the first row.
txtPoints.Text = reader[0].ToString(); // Read the contents of the first column
}
conn.Close();
}
The usual reason for this is a null or empty string i.e. txtCustomerID.Text has no value so the query being sent to the server is:
SELECT forename, Surname FROM customer WHERE [customerID]=
You can avoid errors like this and SQL Injection, use strongly typed parameters and avoid data truncation using parameterised queries (I have assumed customer ID is an int field)
using (OleDbConnection connName = new OleDbConnection(strCon))
{
String sqlName = "SELECT forename, Surname FROM customer WHERE customerID = #CustomerID";
// Create a command to use to call the database.
using (OleDbCommand commandname = new OleDbCommand(sqlName, connName))
{
//Check the input is valid
int customerID = 0;
if (!int.TryParse(txtCustomerID.Text, out customerID))
{
txtName.Text = "Customer ID Text box is not an integer";
return;
}
connName.Open();
// Add the parameter to the command
commandname.Parameters.Add("#CustomerID", OleDbType.Integer).Value = customerID;
// Create a reader containing the results
using (OleDbDataReader readerName = commandname.ExecuteReader())
{
readerName.Read(); // Advance to the first row.
txtName.Text = readerName[0].ToString();
}
connName.Close();
}
}
You have to encode parameters used in string queries.
String sqlName = String.Format("SELECT forname, Surname FROM customer WHERE customerID={0}",txtCustomerID.Text);
But I advice you against using SQL queries hard-coded in strings. Its easy way for SQL Injection attack. You should use parammeters instead.

Categories

Resources