DatetimePicker sort C# - c#

I have two DateTimePicker control on my win form...and all i want is when the user select the datetimepicker(from: ) and ( To: ) the datagridview shows the selected date and year that the user selected..........here's my code.... i need the sort thing
P.S: i used STORED PROCEDURE
public void period()
{
cnn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "sp_insertcategory";
cmd.Connection = cnn;
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
while (rdr.Read())
{
int n = metroGrid1.Rows.Add();
metroGrid1.Rows[n].Cells[0].Value = rdr[0].ToString();
metroGrid1.Rows[n].Cells[1].Value = rdr[1].ToString();
metroGrid1.Rows[n].Cells[2].Value = rdr[2].ToString();
metroGrid1.Rows[n].Cells[3].Value = rdr[3].ToString();
metroGrid1.Rows[n].Cells[4].Value = rdr[4].ToString();
metroGrid1.Rows[n].Cells[5].Value = rdr[5].ToString();
metroGrid1.Rows[n].Cells[6].Value = rdr[6].ToString();
}
}
cnn.Close();
}

You can achieve the same from SQL query (In your case stored procedure itself). Just add below syntax in your SQL query to sort the data in descending order..
ORDER BY post_datetime DESC //post_datetime is columnName which contains DateTime
ASC can be used if you need sorting in ascending order.
Details about order by can be found at https://www.w3schools.com/sql/sql_orderby.asp

Related

SQL Query not Retrieving All Rows in C# Application

I have a stored procedure created in my SQL Server 2012 database that selects data from multiple tables. In C#, I use this procedure to show data in a datagridview.
Issue: when I execute the query in SQL Server, I get the correct result which returns 3 rows, but in C#, it returns only 2 rows.
Query:
SELECT DISTINCT
Employee.Employee_No AS 'Badge'
,Employee.Employee_Name_Ar AS 'Emp Name'
,Employee.Basic_Salary AS 'Basic'
,Employee.Current_Salary AS 'Current'
,Attendance.Present
,Attendance.Leave
,Attendance.Othe_Leave AS 'OL'
,Pay_Slip.Salary_Amount AS 'Sal. Amt.'
,(ISNULL(Pay_Slip.OverTime1_Amount, 0.00) + ISNULL(Pay_Slip.OverTime2_Amount, 0.00)) AS 'O/T Amt.'
,(ISNULL(Pay_Slip.Salary_Amount, 0.00) + ISNULL(ISNULL(Pay_Slip.OverTime1_Amount, 0.00) + ISNULL(Pay_Slip.OverTime2_Amount, 0.00), 0.00)) AS 'Sal. & O/T'
,Pay_Slip.Trasnport AS 'Allow'
,Pay_Slip.CostofLiving AS 'O.Allow'
,Pay_Slip.Gross_Salary AS 'T Salary'
,Pay_Slip.Insurance1_Amount AS 'ss 7%'
,Pay_Slip.Insurance2_Amount AS 'ss 11%'
,(ISNULL(Pay_Slip.Insurance1_Amount, 0.00) + ISNULL(Pay_Slip.Insurance2_Amount, 0.00)) AS 'Total s.s'
,Pay_Slip.Tax
,Pay_Slip.Personal_Loans AS 'Advance'
,Pay_Slip.Other_Deductions AS 'Ded.'
,Pay_Slip.Net_Salary AS 'Net'
FROM Pay_Slip
LEFT JOIN Employee ON Pay_Slip.Employee_No = Employee.Employee_No
LEFT JOIN Attendance ON Pay_Slip.Employee_No = Attendance.Employee_No
WHERE Pay_Slip.Month = '5'
AND Pay_Slip.Year = '2020'
AND Attendance.Month = '5'
AND Attendance.Year = '2020'
Executing this query in SQL Server returns 3 rows which are the employee slips on May-2020 (They all have values in May-2020).
C# code:
private void dateTimePicker_ReportDate_ValueChanged(object sender, EventArgs e)
{
try
{
DateTime date = dateTimePicker_ReportDate.Value;
String Month = dateTimePicker_ReportDate.Value.ToString("MM");
String Year = dateTimePicker_ReportDate.Value.ToString("yyyy");
String str = "server=localhost;database=EasyManagementSystem;User Id=Jaz;Password=Jaz#2020;Integrated Security=True;";
String query = "Execute EMP_PAY_ATT_Selection #Month, #Year";
SqlConnection con = null;
con = new SqlConnection(str);
SqlCommand cmd= new SqlCommand(query, con);
cmd.Parameters.Add("#Month", SqlDbType.Int).Value = Convert.ToInt32(Month);
cmd.Parameters.Add("#Year", SqlDbType.Int).Value = Convert.ToInt32(Year);
SqlDataReader sdr;
con.Open();
sdr = cmd.ExecuteReader();
if (sdr.Read())
{
DataTable dt = new DataTable();
dt.Load(sdr);
dataGridView_Report.DataSource = dt;
dataGridView_Report.EnableHeadersVisualStyles = false;
dataGridView_Report.ColumnHeadersDefaultCellStyle.BackColor = Color.LightBlue;
}
else
{
dataGridView_Report.DataSource = null;
dataGridView_Report.Rows.Clear();
}
con.Close();
}
catch (Exception es)
{
MessageBox.Show(es.Message);
}
}
Again, when running this, it only returns 2 rows on the datagridview. While it should be 3 rows.
These are the tables:
The DbDataReader.Read method advances the reader to the next record.
There is no way to rewind a data reader. Any methods that you pass it to will have to use it from whatever record it is currently on.
If you want to pass the reader to DataTable.Load(), do not Read from it yourself. If you merely want to know if it contains records, use HasRows.

How to get ID of the Last Inserted Record in SQL using ASP.net

Here is my code
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(Request.QueryString["id"]))
{
string clientId = Context.User.Identity.GetUserId();
if (clientId != null)
{
int id = Convert.ToInt32(Request.QueryString["id"]);
customize1 customize = new customize1
{
client_id = clientId,
product_id = id,
paper_type = Labelpt.Text,
corner = Labelpc.Text,
shipping_type = Labelsp.Text,
text = TextBox3.Text,
amount = Convert.ToInt32(lbResult.Text)
};
customizeModel model = new customizeModel();
Label9.Text = model.Insertcustomize(customize);
con.Open();
SqlCommand cmd2 = con.CreateCommand();
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "select top 1 * from customize1 where client_id='"+clientId+"' order by Id desc ";
cmd2.ExecuteNonQuery();
DataTable dt2 = new DataTable();
SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
da2.Fill(dt2);
foreach (DataRow dr2 in dt2.Rows)
{
customizeid = dr2["Id"].ToString();
}
con.Close();
}
}
}
I need the last row id but my query does not generate any value.I also check my query in SSMS and query is working fine but in asp it is not generating any data and for inserting record i used the concept of class and entity relationship.
Any Solution.
Brother there are two ways:
One is when you insert your row place after the Insert query this:
SELECT SCOPE_IDENTITY()
For example:
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
SELECT SCOPE_IDENTITY()
It gives the inserted ID back.
The second way is this query;
SELECT id FROM table ORDER BY id DESC LIMIT 1
If you keep struggling with problems be open to ask more.

Sql Query Data Reader Returning True even it's False in C#

Good day!
It's taking me hours why my query returns a true even it's false.
Here's my code.
public SqlDataReader Check(BEL bel) {
SqlCommand cmd = new SqlCommand();
cmd.Connection = dbcon.getcon();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT SUM(Total) as OverallTotal FROM table WHERE Id=#Id AND DateFrom=#From AND DateTo=#To AND Status='Without'";
cmd.Parameters.AddWithValue("#Id",bel.CLEmpID);
cmd.Parameters.AddWithValue("#From", bel.CLPayrollFrom);
cmd.Parameters.AddWithValue("#To", bel.CLPayrollTo);
SqlDataReader dr = cmd.ExecuteReader();
return dr;
}
Suppose the parameterized values are:
#Id = 0001
#From = 1/28/2016
#To = 1/29/2016
Here's my method calling the datareader
SqlDataReader drCheck;
drCheck = bal.Check(bel);
if (drCheck.HasRows == true)
{
drCheck.Read();
// I'm inside the computation of OverallTotal
}else{
drCheck.Close();
// I'm out
}
drCheck.Close();
The problem is, when the value of my "To", for instance, is 1/30/2016, it suppose to go to the false which is out of the true condition but it is not.
Please help. Thanks in advance
In your query, you are have aggregate function. Whether your from & to returns no rows, as you have aggregate function, you always get one row with value at least zero.
In your case you don't need a Reader, you can use ExecuteScalar:
public decimal? Check(BEL bel)
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = dbcon.getcon();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT SUM(Total) as OverallTotal FROM table WHERE Id=#Id " +
"AND DateFrom=#From AND DateTo=#To AND Status='Without'";
cmd.Parameters.AddWithValue("#Id", bel.CLEmpID);
cmd.Parameters.AddWithValue("#From", bel.CLPayrollFrom);
cmd.Parameters.AddWithValue("#To", bel.CLPayrollTo);
object obj = cmd.ExecuteScalar();
decimal? value = null;
if (obj != DBNull.Value)
value = Convert.ToDecimal(obj);
return value;
}
decimal? total = bal.Check(bel);
if (total.HasValue)
{
// do something with the total.Value
}
else
{
}
Look at simple example
SELECT SUM(total1) as tt1, SUM(total2) AS tt2, COUNT(*) AS [Nbr of rows]
FROM (
SELECT 10 AS total1, CAST(NULL AS INT) total2 --
) t
--WHERE 1=2
Generally when the SUMmed column is nullable only COUNT(*) will tell the difference are there any rows selected or no rows selected.
Your query always returns a value even if there are no matching records because you are summing them, so you get NULLin case of no records and in the case of all matching records' values are NULL. You'll get 0 if there are records and the sum-result is 0(including NULL values which will be counted as 0).
You could use following approach that uses a different query to return both informations:
public bool GetOverAll(int id, DateTime payrollFrom, DateTime payrollTo, out double? overall)
{
overall = null;
string sql = #"
;WITH Data AS(
SELECT t.*
FROM table
WHERE Id = #Id
AND DateFrom = #From
AND DateTo = #To
AND Status = 'Without'
)
SELECT HasRows = CAST(CASE WHEN EXIST( SELECT 1 FROM CTE )
THEN 1 ELSE 0 END AS bit),
OverallTotal = SUM(Total)
FROM CTE";
using (var con = new SqlConnection("connectionstring"))
using (var cmd = new SqlCommand(sql, con))
{
cmd.Parameters.AddWithValue("#Id", id);
cmd.Parameters.AddWithValue("#From", payrollFrom);
cmd.Parameters.AddWithValue("#To", payrollTo);
con.Open();
using (var rd = cmd.ExecuteReader())
{
if (rd.Read())
{
bool hasRows = rd.GetBoolean(0);
if (!rd.IsDBNull(1))
overall = rd.GetDouble(1);
return hasRows;
}
else
{
throw new Exception("This should never be the case!");
}
}
}
}
You now know if there were matching records or not:
double? overall;
bool hasRows = GetOverAll(id, payrollFrom, payrollTo, out overall);
if(hasRows && overall.HasValue)
{
// matching records and the sum of these values was not NULL (possible if nullable column and all values were NULL)
double total = overall.Value;
}

SqlDataReader not reading any row apart from first

New to stackoverflow and very much a c# beginner
Currently creating a form which produces a bar chart from data stored in a database. The chosen record is identified by pID (patient's ID) and tdate (Test date). These values are determined by 2 combo boxes that the user can select from, The problem I am having is that only the first and last records stored in the database are populating the barchart.
if (radioButtonTestResult.Checked)
{
foreach (var series in TestResultBarChart.Series)
{
series.Points.Clear();
}
string tdate = comboBox2.Text;
using (SqlConnection connection = new SqlConnection(#"Data Source= (LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MMSEDB.mdf;Integrated Security=True"))
{
connection.Open();
string sql = "SELECT T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,T_REGISTRATION_SCORE,T_ORIENTATION _SCORE,T_TIME FROM TEST_RESULTS WHERE P_ID='" + pID + "' AND T_DATE='"+ tdate +"'";
using(SqlCommand command = new SqlCommand(sql, connection))
{
command.CommandTimeout = 3600;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
{
MessageBox.Show("hello4");
String clockScoreString = reader["T_CLOCK_SCORE"].ToString();
MessageBox.Show(clockScoreString);
clockScore = Int32.Parse(clockScoreString);
String langScoreString = reader["T_LANGUAGE_SCORE"].ToString();
langScore = Int32.Parse(langScoreString);
String recallScoreString = reader["T_RECALL_SCORE"].ToString();
recallScore = Int32.Parse(recallScoreString);
String regScoreString = reader["T_REGISTRATION_SCORE"].ToString();
regScore = Int32.Parse(regScoreString);
String orientScoreString = reader["T_ORIENTATION_SCORE"].ToString();
orientScore = Int32.Parse(orientScoreString);
String timeScoreString = reader["T_TIME"].ToString();
timeScore = Int32.Parse(timeScoreString);
}
reader.Close();
}
}
this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score", langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);
}
}
Here is a pic of the data:
Test_results_table
here is a pic of the interface with the first record working:
interface
I know this has something to do with the reader but can't work out how to get to function correctly
Any help is very much appreciated
You are reading in a loop all the returned values, then exit from the loop and use just the last value to set your Points. You should move the Point settings inside the loop
....
while (reader.Read())
{
clockScore = Convert.ToInt32(reader["T_CLOCK_SCORE"]);
langScore = Convert.ToInt32(reader["T_LANGUAGE_SCORE"]);
recallScore = Convert.ToInt32(reader["T_RECALL_SCORE"]);
regScore = Convert.ToInt32(reader["T_REGISTRATION_SCORE"]);
orientScore = Convert.ToInt32(reader["T_ORIENTATION_SCORE"]);
timeScore = Convert.ToInt32(reader["T_TIME"]);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score", langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);
}
reader.Close();
Note that your query is built using string concatenation. This is a well known problem with database code. Never do it and use a parameterized query
EDIT
Looking at your comment below, I repeat the advice to use a parameterized query instead of string concatenation. Not only this avoid Sql Injection hacks but also you don't leave the job to understand the meaning of your values to the database engine
DateTime tDate = Convert.ToDateTime(comboBox2.Text);
......
string sql = #"SELECT
T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,
T_REGISTRATION_SCORE,T_ORIENTATION_SCORE,T_TIME
FROM TEST_RESULTS
WHERE P_ID=#id AND T_DATE=#date";
using(SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#id", SqlDbType.Int).Value = pID;
command.Parameters.Add("#date", SqlDbType.Date).Value = tdate;
command.CommandTimeout = 3600;
using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
{
while (reader.Read())
....
In this example I assume that the variable pID is of type integer and the variable tDate is of type DateTime matching the type of the database fields. This doesn't leave any doubt to the database engine on your values.
Of course if the fields are of different type then you should change the SqlDbType accordingly.

C# + mysql I want to select 1000 rows then update those selected rows

I am going to have multiple processes running at the same time so what I tried to do here is fetch 1000 rows and then update the rows i selected.. below are my Select and Update functions notice i call the update function right after closing the connection in the select function
public List<string> Select()
{
string set;
string query = "SELECT * FROM master WHERE attempted='0' LIMIT 1000";
List<string> list = new List<string>();
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
while (list.Count() < 1000)
{
dataReader.Read();
string email = dataReader["email"].ToString();
var m = dataReader["attempted"];
if (m.ToString() == "0")
{
list.Add(email);
}
}
dataReader.Close();
this.CloseConnection();
Update();
return list;
}
else
{
return list;
}
}
public void Update()
{
if (this.OpenConnection() == true)
{
string query = "UPDATE master SET attempted='1' WHERE ( SELECT * FROM master WHERE attempted='0' LIMIT 1000 )";
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.CommandText = query;
cmd.ExecuteNonQuery();
this.CloseConnection();
}
}
the exception i am getting it operand must contain 1 column(s)..
What am I doing wrong?
Why can't you just create a separate column, or even a table? Then write a basic Query at the SQL level or a Procedure to modify the value? Then the other applications can just test the value of the column or table.
Example:
UPDATE [dbo].[Customer]
SET [GotEmail] = 1
WHERE (
SELECT [Email]
FROM [dbo].[Customer]
);
Or something basic like that? Another example would be:
UPDATE accounts
SET (contact_last_name, contact_first_name) =
(SELECT last_name, first_name FROM salesmen
WHERE salesmen.id = accounts.sales_id);
Does a simple query like so not solve your issue?
If my response is not clear... I'll try and clarify my thought process.

Categories