How to hold a SQL SUM() query int a Variable - c#

Good day.
I have an SQL query in C# as shown.
using (SQLiteConnection con = new SQLiteConnection(Connection.DatabaseLocationString))
{
SQLiteCommand cmd = null;
string query =
String.Format("SELECT MONTH(SaleDate) month,
SUM(AmountPaid) sum_amountpaid
FROM {0}
WHERE YEAR(SaleDate) = #1
GROUP BY MONTH(SaleDate) ", Sale.TABLE_NAME);
cmd = new SQLiteCommand(query, con);
cmd.Parameters.Add(
new SQLiteParameter("#1", Properties.Settings.Default.ChartYearlyDisplay));
con.Open();
SQLiteDataReader reader = cmd.ExecuteReader();
con.Close();
}
My challenge is, i have never done nor used a query like this. But what i want to achieve is, i want too Get the value of SUM(AmountPaid) for each month, like this.
January = 20000.00
Febuary = 18000.00
March = 10000.00
.......and so on.
But i really dont know how too come of that.
please i need your help, Thanks.

You just need to loop over the returned results using the SQLiteDataReader
SQLiteDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
Console.WriteLine(reader["month"].ToString());
Console.WriteLine(reader["sum_amountpaid"].ToString());
}
con.Close();
Of course, if you need to return this data, you need a data structure where you can store the results like a List<T>
// The class where you keep the value for a single month...
public class MonthAmount
{
public int Month {get;set;}
public decimal Amount {get;set;}
}
....
// A List where each month of data will be added...
List<MonthAmount> amountData = new List<MonthAmount>();
while(reader.Read())
{
// Create the instance of MonthAmount for the current month..
MonthAmount m = new MonthAmount()
{
Month = Convert.ToInt32(reader["month"]);
Amount = Convert.ToDecimal(reader["sum_amountpaid"]);
}
// Add it to the list...
amountData.Add(m);
}
reader.Close();
// Return the info to the caller....
return amountData;
Also according to SQLite docs, there is no MONTH or YEAR functions available, you should use strftime with an appropriate settings. You could try with
string query = $"SELECT strftime('%', SaleDate) month,
SUM(AmountPaid) sum_amountpaid
FROM {Sale.TABLE_NAME}
WHERE strftime('%Y', SaleDate) = #1
GROUP BY strftime('%m', SaleDate)";
And if I am not wrong, the result of this strftime function is a string not an integer (IE '03' for March, '2017' for year) so perhaps you should create a parameter with the correct datatype.

Related

SQL Query Selecting data from a specific time period

So im trying to select students, rooms and so on from a specific time period which is between 01-01-2020 and 30_06-2020. I tried googleing to see if i could find the answer but it seems tricky to just find something that will work for my instance
public static List<Student_Room> GetFirstSemesterStudents(int id)
{
List<Student_Room> studentRoomList = new List<Student_Room>();
string query = $"select Leasing.Student_No, Leasing.Room_No, Student.Name, Leasing.Date_From, Leasing.Date_To from Leasing,Student where Leasing.Date_from = '01012020' AND Leasing.Date_To = '30062020' AND Dormitory_No = #id";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#id", id);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Student_Room studentRoom = new Student_Room();
studentRoom.Student_No = Convert.ToInt32(reader["Student_No"]);
studentRoom.Student_Name = Convert.ToString(reader["Name"]);
studentRoom.Room_No = Convert.ToInt32(reader["Room_No"]);
studentRoom.Date_From = Convert.ToDateTime(reader["Date_From"]);
studentRoom.Date_To = Convert.ToDateTime(reader["Date_To"]);
studentRoomList.Add(studentRoom);
}
return studentRoomList;
}
}
}
The main problem is just that i dont know how to write the query, ther rest should be correct. i get the "Conversion failed when converting date and/or time from character string" when i try to run the function on the site
We just started learning about this stuff so im still not the best at queries and dont know much, thank for looking at it and helping appriciate it :D
make sure in database you have to define the datatype for date as the same in the Student_Room class, either date alone or datetime , if you want to chage to date alone as it is defined in the class the you can use
studentRoom.Date_From = DateTime.Parse(reader["Date_From"]);
studentRoom.Date_To = DateTime.Parse(reader["Date_To"]);

How to extract date and month part from datetime field in database

I have a datetime column named submitted_date. One of it's value in database is 5/12/2017 11:09:50 AM. Now I want to extract only date and month part of it. How to display it in a format like "May-12".
My code is here,
using (SqlConnection con = obj.getcon())
{
con.Open();
string query = "SELECT submitted_date FROM sample";
using (SqlCommand command = new SqlCommand(query, con))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
string x_val = reader[0].ToString(); // 5/12/2017 11:09:50 AM
}
}
}
con.Close();
}
To get the alphabetic month name you can use MMM. Here is the code:
var result = DateTime.Parse(reader[0].ToString())
.ToString("MMMM-dd", CultureInfo.InvariantCulture);
//if reader[0].ToString(): 5/12/2017 11:09:50 AM then
//result: May-12
Use DATEPART directly on SQL and you're done.
You can do this with the following, but you will need to know which culture so as to get the month name in the correct language. I have used the US culture in this example:
string s = reader.GetDateTime(0).ToString("MMMM-dd", CultureInfo.CreateSpecificCulture("en-US"));
This also assumes that your submitted_date column is NOT NULL.
You can write query like:
Convert(varchar(20),submitted_date,107) submitted_date which will return date on Dec 12, 2016.
Try this:
from:
string x_val = reader[0].ToString(); // 5/12/2017 11:09:50 AM
To:
string x_val =DateTime.Parse(reader[0].ToString()).ToString("MMM-dd");

Reading an SQLite DateTime value from database and assigning it to a C# string variable

I have a database with a datatable which includes a DateTime column among other things. When using SQL server, I could read the DateTime value from the database using the following code:
SqlCommand getdate = new SqlCommand("SELECT * FROM EMPinfo WHERE id = #employeeId", connect);
getdate.Parameters.AddWithValue("#employeeId", listViewEmployee.SelectedItems[0].SubItems[2].Text);
getdate.Connection = connect;
connect.Open();
SqlDataReader readList = getdate.ExecuteReader(CommandBehavior.CloseConnection);
while (readList.Read())
{
lblEmpDob.Text = ((DateTime)readList["dob"]).ToString("d");
}
After changing the code to run with SQLite:
SQLiteConnection connect = new SQLiteConnection(#"Data Source=quotevodata.db;");
SQLiteCommand getlistname = new SQLiteCommand("SELECT * FROM EMPinfo WHERE id = #employeeId", connect);
getlistname.Parameters.AddWithValue("#employeeId", listViewEmployee.SelectedItems[0].SubItems[2].Text);
getlistname.Connection = connect;
connect.Open();
SQLiteDataReader readList = getlistname.ExecuteReader(CommandBehavior.CloseConnection);
while (readList.Read())
{
lblEmpDob.Text = ((DateTime)readList["dob"]).ToString("d");
}
I keep getting the following error: "String was not recognized as a valid datetime."
I've tried different combinations and declaration of variables but it's not working out. What is the correct configuration to read DateTime values out of an SQLite database?
SQLite does not have a built-in DateTime object, but rather stores them as Text, Real, or Int values.
From your error, you can infer that it's outputting as text; Which according to SQLite documentation should be in the format of "YYYY-MM-DD HH:MM:SS.SSS"
There are various ways you could parse this to a DateTime object, but I'll use RegEx:
public static DateTime ConvertToDateTime(string str)
{
string pattern = #"(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})\.(\d{3})";
if (Regex.IsMatch(str, pattern))
{
Match match = Regex.Match(str, pattern);
int year = Convert.ToInt32(match.Groups[1].Value);
int month = Convert.ToInt32(match.Groups[2].Value);
int day = Convert.ToInt32(match.Groups[3].Value);
int hour = Convert.ToInt32(match.Groups[4].Value);
int minute = Convert.ToInt32(match.Groups[5].Value);
int second = Convert.ToInt32(match.Groups[6].Value);
int millisecond = Convert.ToInt32(match.Groups[7].Value);
return new DateTime(year, month, day, hour, minute, second, millisecond);
}
else
{
throw new Exception("Unable to parse.");
}
}
docs: http://www.sqlite.org/datatype3.html
Thanks for the answers, I finally got it to work by changing the INSERT statement to SQLite format as suggested:
string empDob = dateDOB.Value.ToString("yyyy-MM-dd");
//I then inserted this string into the database with the column configured as a "DATE" datatype.
After that, I used the following statements to read and format the date to usable string and it worked beautifully:
DateTime dateOfBirthEmp = DateTime.Parse(readList["dob"].ToString());
lblEmpDob.Text = dateOfBirthEmp.ToString("d");
I really appreciate the help.
Why do you convert 2 times?
If you have a Date column in SQLite the provider can manged that for you.
You can direct insert as DateTime and read as DateTime.
It's feels a bit hacky but this is the only solution I was able to come up with.
It just creates a new column, copies all the values in DateTime format to the new column and deletes the old time string column.
DataTable dt = GetDataTable();
string tc = "TimeColumnName";
dt.Constraints.Clear();
int ordinal = dt.Columns[tc].Ordinal;
dt.Columns[tc].ColumnName = "TSOLD";
dt.Columns.Add(tc, typeof(DateTime));
foreach (DataRow row in dt.Rows) row[tc] = Convert.ToDateTime(row["TSOLD"]);
// remove "OLD" column
dt.Columns.Remove("TSOLD");
dt.Columns[tc].SetOrdinal(ordinal);
dt.Constraints.Add(new UniqueConstraint(dt.Columns[tc]));

Get value from class

So i have a class Take for connecting to mysql. In that class I have a method to call a query to take the last record from mysql table.
public void Balance()
{
string query = "SELECT balance FROM history ORDER BY id DESC LIMIT 1 ";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.ExecuteNonQuery();
}
}
In the main form I'm calling that class and that method
take.Balance();
I know, that from code above, i don't get any value but NULL, so i am asking how i can take value from that query and put it in the TextBox in the main form?
Personally, I think you should improve your basic knowledge of programming. There are two big problems in your example code:
You want to get the value, but your function is void, not return anything even set the value to some variable
ExecuteNonQuery is not your case.
For example:
public string Balance()
{
string query = "SELECT balance FROM history ORDER BY id DESC LIMIT 1 ";
if (this.OpenConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
return cmd.ExecuteScalar();
}
}
Let's have look:
// You probably want to return value: decimal, not void
public decimal Balance() {
// Make sql readable
string query =
#"SELECT balance
FROM history
ORDER BY id DESC
LIMIT 1 ";
// do not cache connection, but create a new one instead
using (MySqlConnection conn = new MySqlConnection(connectionStringHere)) {
conn.Open();
// wrap IDisposable into using
using (MySqlCommand cmd = new MySqlCommand(query, conn)) {
// you want to return values: ExecuteReader (or ExecuteScalar)
// instead of ExecuteNonQuery
using (var reader = cmd.ExecuteReader()) {
if (reader.Read())
return Convert.ToDecimal(reader.GetValue(0));
else
return 0m; // cursor is empty, let's return 0
}
}
}
}
There are two things to consider. First, the query
"SELECT balance FROM history ORDER BY id DESC LIMIT 1"
is a query in the sense that some useful data from the database should be returned, it should not be executed with a the method ExecuteNonQuery, which is intended to return the number of rows affected by a non-query statement. Second, the return type of Balance would have to be changed to some other type than void, say int or something similar, which would have to be returned to the caller.

Store the results in memory (List) using c#

I want to store many record that I query from database in list , one record has 10 fields, in order to loop it later.
But I have no idea to do that. Anyone can answer me please.
Below is a good practice to store data and loop through among them.
Create Model/POCO class as:
public class DataClassName
{
public int Id { get; set; }
public string Name { get; set; }
//Create properties according to your fields
}
Fill and get data list:
public List<DataClassName> GetDataList()
{
List<DataClassName> dataList = new List<DataClassName>();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "select * from TargetTableName";
cmd.CommandType = CommandType.Text;
try
{
using (SqlConnection connection =
new SqlConnection("YourConnectionString"))
{
cmd.Connection = connection;
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
dataList.Add(
new DataClassName()
{
Id = Convert.ToInt32(reader["ID"]),
Name = Convert.ToString(reader["Name"])
//Set all property according to your fields
});
}
}
}
}
catch(Exception ex_)
{
//Handle exception
}
return dataList;
}
Save data that is returned from GetDataList() into your datalist and loop through among the data as required.
Here's how you'd go about storing it in a DataTable:
SqlConnection conn = new SqlConnection("yourConnectionStringHere");
SqlCommand GetData = new SqlCommand();
GetData.Connection = conn;
GetData.CommandText = "select * from yourTable"; // or whatever your query is, whether ad hoc or stored proc
// add parameters here if your query needs it
SqlDataAdapter sda = new SqlDataAdapter(GetData);
DataTable YourData = new DataTable();
try
{
sda.Fill(YourData);
}
catch
{
sda.Dispose();
conn.Dispose();
}
If you have 10 fields, you'd be hard-pressed to store your data in a List<T> object. Your best bet would be to create a class tailored to the data you are looking to retrieve (if you want to take it a step further than the DataTable implementation above) with corresponding properties/fields.
Perhaps you could give a bit more information...
If you use the entity framework or similar to query the database, it will probably return an enumerable object.. you just need to call .ToList() on this to save it as a list.
Do you mean that you want to store this across web requests? Then you could store it in the HttpRuntime.Cache collection, allowing for it to expire after some time.
Alternatively store it in a static property. Session is also an option but it doesn't sound like the best option for this

Categories

Resources