I would like to make my not null DateTime column null when I do the sum of the entire table so that I do not get any value for date time 1/1/0001 12:00:00. I would like to add whatever possible statement into this method. I tried to do parse it but it doesn't work, but for Amount it's perfectly fine.
private void SumOfRecords_Button(object sender, RoutedEventArgs e)
{
ObservableCollection<Receipt> receipts = new ReceiptDAO().GetAllReceiptsFromPiName();
Receipt receipt = new Receipt();
if (receipt.DateTime != null)
{
Receipt receipt0 = new Receipt()
{
DateTime = DateTime.TryParse(),
Amount = new ReceiptDAO().SumOfRecords("Amount")
};
receipts.Add(receipt);
this.Dispatcher.Invoke(() => ReceiptList.ItemsSource = receipts);
}
}
This is the method for SumOfRecords where I am writing my query.
public double SumOfRecords(string columnName)
{
ObservableCollection<Receipt> receipts = new ReceiptDAO().GetAllReceiptsFromPiName();
Receipt receipt = new Receipt();
string commandstring;
commandstring = "select Sum(" + columnName + ") from " + getTable();
using (SQLiteConnection connection = ConnectToDatabase())
{
using (SQLiteCommand command = new SQLiteCommand(commandstring, connection))
{
using (SQLiteDataReader reader = command.ExecuteReader())
{
reader.Read();
return reader.GetDouble(0);
}
}
}
}
Just ignore dates when you calculate the sum. Assuming you're using sql server for database.
var where = " WHERE Table.Date <> '0001/01/01 00:00:00'";
commandstring = "select Sum(" + columnName + ") from " + getTable() + where;
You can pass where as a parameter to the method to make it reusable. Based on what database you're using, you may want look into date comparison. Otherwise the concept remains the same.
Related
I am very new to database queries and even more so, Oracle. I am also new to development work and, believe it or not, am creating this an for work purely out of frustration with the current process. Anyway, I am attempting to collect input from a multi-line text box and run a query. Each line corresponds to a single string that needs to be passed into the WHERE statement and the results will be dumped into a data table. Unfortunately, Oracle has still not released its developer tools for VS2019 so I am having to do this the harder way.
UPDATE # 2:
I have completely rebuilt the query since it was not running even when using known working code from another query. Below is what I have pieced together from various places on the interwebs. While debugging, it appears to parse and format the text correctly and pass it into the OracleParameter without issue. I am getting a Missing Expression error but I don't know what I am missing.
var connString =
ConfigurationManager.ConnectionStrings["dB"].ConnectionString;
string query = "SELECT col1, col2, col3, col4 FROM table WHERE col5 IN (";
using (OracleConnection conn = new OracleConnection(connString))
try
{
var input = "";
input = uniLookup.UniList;
var uniList = string.Join(",", Regex.Split(input, #"(?:\r\n|\n|\r)"));
string allParams = uniList;
string formattedParams = allParams.Replace(" ", string.Empty);
string[] splitParams = formattedParams.Split(',');
List<OracleParameter> parameters = new List<OracleParameter>();
using (OracleCommand cmd = new OracleCommand(query, conn))
{
for (int i = 0; i < splitParams.Length; i++)
{
query += #":Uni" + i + ",";
parameters.Add(new OracleParameter(":Uni" + i, splitParams[i]));
{
query = query.Substring(0, (query.Length - 1));
query += ')';
conn.Open();
using (OracleDataReader reader = cmd.ExecuteReader()) <==ERROR
{
if (!reader.HasRows)
{
while (reader.Read())
{
reader.Read();
{
MessageBox.Show(reader.GetString(1));
}
}
}
You can use IN in your where clause in this way to get rows from multiple values as:
string query = "SELECT dummyCol FROM dummytable WHERE altCol IN ("+text+");";
where you just have to change your text as text="'value1','value2','value3'"; this will not produce any syntax error.
You can convert your multi line text into same comma separated values using this :
foreach (String s in textBox1.Text.Split('\n'))
{
text +="'"+ s+"',";
}
text = text.TrimEnd(',');
this will help you achieve what you need. you can ask If there is any confusion.
Your final code will become :
public void GetData()
{
if (string.IsNullOrWhiteSpace(textbox1.Text) || textbox1.Text == "")
{
MessageBox.Show("Please Enter at least 1 Value and Try Again!");
}
else
{
System.Data.DataTable dt = new System.Data.DataTable();
// string[] lines = textbox1.Text.Split('\n');
string text = "";
foreach (String s in textBox1.Text.Split('\n'))
{
text += "'" + s + "',";
}
text = text.TrimEnd(',');
//Connection Credentials
string credentials = "Credentials";
string query = "SELECT dummyCol FROM dummytable WHERE altCol IN ("+text+");";
OracleConnection conn = new OracleConnection(credentials);
try
{
//Open The Connection
conn.Open();
using (OracleCommand cmd = new OracleCommand(query, conn))
{
//Call the Oracle Reader
using (OracleDataReader reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
MessageBox.Show("Unable to Retrieve Data");
return;
}
else if (reader.HasRows)
{
reader.Read();
DataRow row = dt.NewRow();
// create variables to accept reader data for each column
// insert data from query into each column here
dt.Rows.Add(row);
}
}
}
}
}
}
I have a datagridview that holds the bio_id and email. I am iterating through the datagridview to get the time records of the employee based on the bio_id and dates. If I create a MySql syntax in the MySql itself, it gets the right value but when I use the MySqlDataReader, it gives me a null value. Below are the codes:
public MySqlDataReader SendTimeLogs(string fromDate, string toDate, int bioId)
{
using (var cn = new DatabaseConnection().ConnectToMySql())
{
const string query = #"SELECT MIN(scan_time) as 'Time In', MAX(scan_time) as 'Time Out',
TIMEDIFF(MAX(scan_time),MIN(scan_time)) as difference
FROM `filtered_dates`
WHERE bio_id = #bioId AND date BETWEEN #fromDate AND #toDate GROUP BY date ORDER BY date asc";
var cmd = new MySqlCommand(query, cn);
cn.Open();
cmd.Parameters.AddWithValue("#fromDate", fromDate);
cmd.Parameters.AddWithValue("#toDate", toDate);
cmd.Parameters.AddWithValue("#bioId", bioId);
return cmd.ExecuteReader();
}
}
private void SendEmail()
{
var rdr = new EmployeeDataAccess().GetBioIdEmail();
while (rdr.HasRows && rdr.Read())
{
dgvBioIdList.Rows.Add(rdr["bio_id"].ToString(), rdr["email_add"].ToString());
}
for (var i = 0; i < dgvBioIdList.Rows.Count; i++)
{
var message = "Time Logs for Bio ID: " +dgvBioIdList.Rows[i].Cells[0].Value;
var x = new FilteredDatesDataAccess();
var timeLogs = x.SendTimeLogs(dtpStart.Text, dtpStop.Text,
Convert.ToInt32(dgvBioIdList.Rows[i].Cells[0].Value));
var rec = dgvBioIdList.Rows[0].Cells[1].Value.ToString();
Console.WriteLine(message);
Console.WriteLine(rec);
while (timeLogs.HasRows && timeLogs.Read())
{
Console.WriteLine(timeLogs["Time In"] + #" - " + timeLogs["Time Out"]);
}
}
}
I get the Console.WriteLine(message); and Console.WriteLine(rec); just fine but my while loop is not being written in the console. Can you help? Thank you.
C# SQLite Query
String sql = #"SELECT user FROM '" + channel + "' ORDER BY currency DESC LIMIT 10";
You have a problem with your query. The SELECT extracts only one column from the table represented by the variable channel. So your GetString(1) in the reader loop fails because there is no field at index 1 (arrays start at index zero). You need to change that GetString index.
Then there is a problem in the return value. You say that you want to return a single string but there is no return statement and you don't have any single string to return
You could write
public string top10()
{
List<string> toplist = new List<string>();
String sql = "SELECT user FROM '" + channel + "' ORDER BY currency DESC LIMIT 10";
using (cmd = new SQLiteCommand(sql, myDB))
{
using (SQLiteDataReader r = cmd.ExecuteReader())
{
while (r.Read())
{
toplist.Add(r.GetString(0));
}
}
}
return string.Join(",", toplist);
}
or change the return type of the method to
public List<string> top10()
{
.....
return toplist;
}
or to
public string[] top10()
{
.....
return toplist.ToArray();
}
I have changed your internal array to a List<string> because if you have less than 10 records your array will have empty strings instead a list will return just the rows found.
You may also try this answer.
public string getTop10()
{
List<string> Toplist = new List<string>();
string connection = "YourConnectionString";
using (var con = new SQLiteConnection { ConnectionString = connection })
{
using (var command = new SQLiteCommand { Connection = con })
{
con.Open();
command.CommandText = #"SELECT user FROM #channel ORDER BY currency DESC LIMIT 10";
command.Parameters.AddWithValue("#channel", channel);
using (var r = command.ExecuteReader())
{
while(r.Read())
{
Toplist.Add(r.GetString(0));
}
}
}
}
return string.Join(",", Toplist);
}
I'm trying to implement date-picker functionality in my project, but I can't do it quite right. I'm trying to pass the date-picker value in my oracle string so that it will compare with my db column and return results on the date criteria...
Whenever I pass it to the select statement it won't generate errors particularly but on button click it doesn't perform anything except it shows "not connected".
str = "Select * from sania.doctor where APPOINTMENT_DATE = "+ datepicker1.value;
It is clear it is logical mistake but I'm new to this C# concepts I need someone to tell me how to pass it and then display the results as well.
private void button1_Click(object sender, EventArgs e)
try
{
OracleCommand com;
OracleDataAdapter oda;
string ConString = "Data Source=XE;User Id=system;Password=sania;";
OracleConnection con = new OracleConnection(ConString);
{
// string id = dateTimePicker1.Text.Trim();
con.Open();
// str = "Select * from sania.doctor where APPOINTMENT_DATE = " + dateTimePicker1.value;
str = "select * from sania.doctor where APPOINTMENT_DATE to_date('"+dateTimePicker1.Value.ToString("yyyyMMdd") + "', 'yyyymmdd')";
com = new OracleCommand(str);
oda = new OracleDataAdapter(com.CommandText, con);
dt = new DataTable();
oda.Fill(dt);
Rowcount = dt.Rows.Count;
//int val = 0;
for (int i = 0; i < Rowcount; i++)
{
dt.Rows[i]["APPOINTMENT_DATE"].ToString();
//if (id == dateTimePicker1.Value)// this LINE SHOWS ERROR--because it is a string and I am using date with it. Don't know conversion
// {
// val = 1;
//}
}
// if (val == 0)
// { MessageBox.Show("INVALID ID"); }
// else
// {
DataSet ds = new DataSet();
oda.Fill(ds);
if (ds.Tables.Count > 0)
{
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
else { MessageBox.Show("NO RECORDS FOUND"); }
}
}
//}
catch (Exception)
{ MessageBox.Show("not connected"); }
}
Do not put values into SQL directly, use bind variables/parametes instead. For Oracle:
// :prm_Appointment_Date bind variable declared within the query
String str =
#"select *
from sania.doctor
where Appointment_Date = :prm_Appointment_Date";
....
using(OracleCommand q = new OracleCommand(MyConnection)) {
q.CommandText = str;
// datepicker1.Value passed into :prm_Appointment_Date via parameter
q.Parameters.Add(":prm_Appointment_Date", datepicker1.Value);
...
}
Doing like that you can be safe from either SQL Injection or Format/Culture differences
I'm populating the following WPF datagrid:
Using the following method:
private void ButtonFilterWorkflowWhenClick(object sender, RoutedEventArgs e)
{
var db = new DatabaseHandle();
dataGridWorkflow.ItemsSource = db.DisplayHealthIndicator(DateTime.Now, DateTime.Now);
labelWorkflowLastLoaded.Content = "Last Loaded at " + DateTime.Now.ToString(CultureInfo.InvariantCulture) + " with " +
dataGridWorkflow.Items.Count.ToString(CultureInfo.InvariantCulture) + " total events.";
}
Which references the following class object:
public DataView DisplayHealthIndicator(DateTime startDate, DateTime endDate)
{
string queryString = "[marlin].[support_retrieve_workflow_history]";
using (SqlConnection connection = new SqlConnection(GetConnectionString()))
{
using (var cmd = new SqlCommand(queryString, connection))
{
connection.Open();
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("date_from", startDate.Date);
cmd.Parameters.AddWithValue("date_to", endDate.Date);
var reader = cmd.ExecuteReader();
var dt = new DataTable();
dt.Load(reader);
connection.Close();
return dt.DefaultView;
}
}
}
I'm trying to find a way that I can find the sum of the total column so I can add it to my label but having no success. I can do this with a second query but I'd like to avoid that wherever possible. How should I approach this problem?
You may have to enumerate the rows in your DataView, something like:
dataGridWorkflow.ItemsSource = db.DisplayHealthIndicator(DateTime.Now, DateTime.Now);
DataView dv = (DataView)dataGridWorkflow.ItemsSource;
DataRowCollection drc = dv.Table.Rows;
IEnumerator rowEnum = drc.GetEnumerator();
int sum = 0;
while (rowEnum.MoveNext())
{
sum += (int)((DataRow)rowEnum.Current)[3];//assuming the 'Total' column has index 3.
}
labelWorkflowLastLoaded.Content = "Last Loaded at " + DateTime.Now.ToString(CultureInfo.InvariantCulture) + " with " + sum.ToString(CultureInfo.InvariantCulture) + " total events.";
Edit: I changed it so that you should be able to just copy and paste into your code.