DataTable not showing minutes and seconds - c#

string command = "select x,y,z,t,ModifiedDate " +
" from ZZ where PP='" + XX + "' and Type='" + YY + "' order by ModifiedDate";
connection();
SqlCommand command = new SqlCommand(command, con);
command.CommandType = CommandType.Text;
SqlDataAdapter da = new SqlDataAdapter(command);
DataTable dt = new DataTable();
da.Fill(dt);
ModifiedDate is a DateTime - in SQL i see "2019-07-23 12:02:35.283"
But when i want to see "dt" in C# i only see "2019-07-23"
how can i see full time with minutes and seconds?
The type of the column in the DataTable is DateTime. ZZ is a table.

You could try setting the row to something like this:
((DateTime)row[0]).ToString("yyyy-MM-dd HH:mm:ss")
Like how you said in the comments just add the formatting to your ToString() when assigning to the variable.

What you had shouldn't even compile, since you can't declare both a string and an SqlCommand object with the same name in the same scope. Run the query like this:
string sql = #"
select x,y,z,t,ModifiedDate
from ZZ
where PP= #XX and Type= #YY
order by ModifiedDate";
DataTable dt = new DataTable();
// .Net connection pooling means you really do want a new connection object most of the time. Don't try to re-use it!
// The "using" blocks make sure your objects are closed and disposed, even if an exception is thrown
using (var con = new SqlConnection("connection string here"))
using (var cmd = new SqlCommand(sql, con))
using (var da = new SqlDataAdapter(cmd))
{
//use the actual column types and lengths from your database here
cmd.Parameters.Add("#XX", SqlDbType.NVarChar, 30).Value = XX;
cmd.Parameters.Add("#YY", SqlDbType.NVarChar, 10).Value = YY;
da.Fill(dt);
}
But this still won't fix everything. It's mainly about closing the huge gaping-wide security hole and potential denial-of-service issue in the original code.
The actual issue from the question is in a different place than this code. The time portion of your ModifiedDate column is in the resulting DataTable. Really. I promise. If you don't see it, it's because of a DataView, format string, or other issue at the point where you try to observe or display these results.

There is no Date class in C# - even DateTime.Date() returns another DateTime object with an all zeros time component.
Your problem sounds very much like a Regional Settings issue, or more specifically, CultureInfo in C#. Your default (or "current" as applied by Thread.CurrentThread's CurrentCulture or CurrentUICulture) has its CultureInfo.DateTimeFormat setup to supply date-without-time formatting.
Probably the FullDateTimePattern is set to "yyyy-mm-dd" or something equivalent.

Related

C# and saving date field to MS Access database

I am new to Access and saving data to it. I have a date time field which I used in Visual Studio to make the form and chose date time picker. I am not sure where I am going wrong but I know it is the calendar picker causing the issue. I get error syntax error in insert to statement.
Here is the code I have
string When = qaWhendateTimePicker.Value.ToString("HH:mm:ss.fff");
then my save query
SQLString = "INSERT INTO QAAnswers (QuestionID,CallMonitorNumber,When) VALUES('"+QuestionID + "','" + CallMonitorNumber + "','" + When + "');";
This is of course the shorten version. But for the love of me if I take out the when it saves to the database fine
The Access database I have WHEN SET AS DATE / TIME.
Should I have it set to text? I would think no because then I can not pull queries based on date.
Thanks in advance as I been at this for many hours.
UPDATE
Per comment below i have changed the syntax. Here is what i have. If i put the .value or .date it does not work. I am sure it is something I am doing wrong. I get the error failed to convert parameter value from datetimepicker to datetime. Thanks as I am learning a lot doing this in access.
ad.InsertCommand = new OleDbCommand("insert into QAAnswers ([CallMonitorNumber],[When],[ProperGreeting],[AssureHelp],[AccountVerification],[ConfirmCaller],[ProperPoliciesSolutions],[ProperPoliciesAdmin],[AppropriateTools],[TroubleshootingSteps],[ConfirmResolved],[CustomerEducation],[CSATSurvey],[ThanksCallerBrand],[ProfessionalToneAttitude],[CustomerInvolved],[CallPace],[Empathy],[PhoneEtiquette],[DiffuseEscalated],[UnacceptableCallPractice],[Notes],[ScorePotential],[ScoreActual],[FinalScore]) values (#CallMonitorNumber,#When,#ProperGreeting,#AssureHelp,#AccountVerification,#ConfirmCaller,#ProperPoliciesSolutions,#ProperPoliciesAdmin,#AppropriateTools,#TroubleshootingSteps,#ConfirmResolved,#CustomerEducation,#CSATSurvey,#ThanksCallerBrand,#ProfessionalToneAttitude,#CustomerInvolved,#CallPace,#Empathy,#PhoneEtiquette,#DiffuseEscalated,#UnacceptableCallPractice,#Notes,#ScorePotential,#ScoreActual,#FinalScore)", con);
ad.InsertCommand.Parameters.Add("#QuestionID", OleDbType.VarChar).Value = agentIDNumbertextBox.Text.ToString();
ad.InsertCommand.Parameters.Add("#CallMonitorNumber", OleDbType.VarChar).Value = qaCallMonitorNumbertextBox.Text.ToString();
ad.InsertCommand.Parameters.Add("#When", OleDbType.DBDate).Value = qaWhendateTimePicker;
UPDATED ANSWER
I finally figured it out. Not sure if this is the best way but i just ignored the datetimepicker. I wish i could use the datepicker. Instead i just input the date it was added in by using this statement (shorten version ) Notice the [when] and the Date() .
DateTime now = DateTime.Now;
ad.InsertCommand = new OleDbCommand("insert into QAAnswers ([CallMonitorNumber],[When]) values (#CallMonitorNumber,Date())", con);
I hope this helps someone else. I really do not like using access for a DB but that is what i have to work with .
I gave points to marc as i never heard of parametrized query
You should use a parametrized query to do the insert, to avoid SQL injection attacks!
Something like this:
SQLString = "INSERT INTO QAAnswers (QuestionID, CallMonitorNumber, When) VALUES(?, ?, ?);";
and then when you prepare your insert statement, you need to add three parameters (in Access typically defined as p1, p2, p3) and assign values to those.
using (OleDbConnection conn = new OleDbConnection(YourConnectionStringHere))
using (OleDbCommand cmd = new OleDbCommand(SQLString, conn))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("p1", OleDbType.VarChar, 50).Value = QuestionID;
cmd.Parameters.Add("p2", OleDbType.VarChar, 50).Value = CallMonitorNumber;
cmd.Parameters.Add("p3", OleDbType.DBDate).Value = When;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
This will also take care of avoiding issues with dates in string format, and issues with single quotes and all those messy things.
You can use this method also:-
write your insert query in a stored procedure(or you can use query directly) then call it in your method
string strcon = ConfigurationManager.ConnectionStrings["YourConnectionStringName"].ConnectionString;
con.ConnectionString = strcon;
con.Open();
SqlCommand cmd = new SqlCommand("[Your_StoredProcedureName]", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("#value1", value1);
da.SelectCommand.Parameters.AddWithValue("#value2", value2);
da.SelectCommand.Parameters.AddWithValue("#value3", value3);
int result = da.SelectCommand.ExecuteNonQuery();
return result ;
I finally figured it out. Not sure if this is the best way but i just ignored the datetimepicker. I wish i could use the datepicker. Instead i just input the date it was added in by using this statement (shorten version ) Notice the [when] and the Date() .
DateTime now = DateTime.Now;
ad.InsertCommand = new OleDbCommand("insert into QAAnswers ([CallMonitorNumber],[When]) values (#CallMonitorNumber,Date())", con);

Explain me this SELECT dbo.TableName(#variable) statement

I'm working on one program that I need to modify a little. There's one SQL statement I don't understand what it does (or basically how it does it).
string query = "SELECT dbo.BusinessMinutes(#start,#end,#priorityid)";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add("#start", SqlDbType.DateTime).Value = start;
cmd.Parameters.Add("#end", SqlDbType.DateTime).Value = end;
cmd.Parameters.Add("#priorityid", SqlDbType.UniqueIdentifier).Value = priorityId;
SqlDataAdapter READER = new SqlDataAdapter();
READER.SelectCommand = cmd;
DataTable table = new DataTable();
READER.Fill(table);
if (table.Rows.Count == 1)
{
minutes = (int)table.Rows[0][0];
}
So can someone explain me the SELECT statement there. The end result (minutes) is as expected so it works but that syntax confuses me. Is this somehow equal to SELECT * FROM dbo.BusinessMinutes WHERE...
Is this commonly used and does this syntax has some special name so I could name my question better? Thank you in advance.
dbo.BusinessMinutes has to be a UDF (User Defined Function) that returns a simple scalar value based on a starting date, an ending date and a priority indicator.
Scalar functions, be it UDF or native, can be used in a SELECT statement to produce a field in the returned resultset. Thus, the code you have is perfectly legal.
For more information about scalar UDF, read this MSDN article.
As a side note, a better implementation for that code would be this:
string query = "SELECT dbo.BusinessMinutes(#start,#end,#priorityid)";
using (SqlCommand cmd = new SqlCommand(query, con))
{
cmd.Parameters.Add("#start", SqlDbType.DateTime).Value = start;
cmd.Parameters.Add("#end", SqlDbType.DateTime).Value = end;
cmd.Parameters.Add("#priorityid", SqlDbType.UniqueIdentifier).Value = priorityId;
// assuming connection is already open
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader.Read()) minutes = reader.GetInt32(0);
}
}
If all you want is to init the minutes variable, using SqlDataReader will be more efficient and performant than creating a SqlDataAdapter and a DataTable. The using statements will also make sure your SqlCommand and SqlDataReader objects gets disposed of properly.
It is not a table name. I think you call into a FUNCTION.
how to create and call scalar function in sql server 2008
has more explanations and examples.

C# No value given for 1 or more required parameters, but I can't see why

I have posted the code I have below
I am trying to get the data from an Access 2002-2003 database
If I take out everything after the WHERE clause and just use "SELECT * FROM [{0}] then it takes all the data from the table with no problems. I have double checked the field names, they are definitely correct. I have more than 1 table with the same field names, so I thought maybe I would need to include the table name before the field name, but with or without the table I still get the same exception. I have tried moving the position of the square brackets, again with no success...
Even if I include only one of the WHERE clauses, the code no longer works, and I can't for the life of me work out why.. I have spent hours looking at numerous posts here and on other sites related to this error, but none of the suggestions have helped me..
The Destination field is a 'memo' field in Access.
The Next Collection fields are date fields, GVars.currentDate is set earlier in the code to be today's date (with the time portion set to 00:00:00).
GVars.thisFY is also set programatically as a string prior to this.
Any tips would be appreciated.
string sql;
OleDbDataAdapter adapter;
sql = string.Format(
"SELECT * FROM [{0}] WHERE {0}.[Destination] = #Destination AND {0}.[Next Collection] BETWEEN #NextCollectionA AND #NextCollectionB"
, GVars.thisFY);
// Create the command object
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
// Add values to the fields
cmd.Parameters.AddWithValue("#Destination", "Henwood");
cmd.Parameters.AddWithValue("#NextCollectionA", GVars.currentDate);
cmd.Parameters.AddWithValue("#NextCollectionB", GVars.currentDate.AddDays(1));
adapter = new OleDbDataAdapter(cmd.CommandText, conn);
System.Diagnostics.Debug.Print(cmd.CommandText);
try
{
adapter.Fill(ds);
GVars.bLblLastUpdate = DateTime.Now.ToString("HH:mm:ss");
}
catch (Exception ex)
{
}
EDIT:
Thanks Vladislav for the answer, corrected code posted below:
string sql;
OleDbDataAdapter adapter;
sql = string.Format(
"SELECT * FROM [{0}] WHERE [{0}].[Destination] = #Destination AND [{0}].[Next Collection] BETWEEN #NextCollectionA AND #NextCollectionB"
, GVars.thisFY);
// Create the command object
OleDbCommand cmd = new OleDbCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = sql;
cmd.Connection = conn;
// Add values to the fields
cmd.Parameters.Add("#Destination", OleDbType.Char).Value = "Henwood";
cmd.Parameters.Add("#NextCollectionA", OleDbType.DBDate).Value = GVars.currentDate;
cmd.Parameters.Add("#NextCollectionB", OleDbType.DBDate).Value = GVars.currentDate.AddDays(1);
adapter = new OleDbDataAdapter(cmd);
try
{
adapter.Fill(ds);
GVars.bLblLastUpdate = DateTime.Now.ToString("HH:mm:ss");
}
Try to specify types for the parameters you add.
Another thing I notice is that to your adapter you are passing only the CommandText.
You should pass the whole command object.

Invalid Column name when implementing search button

I'm working with C# and SQL Sever 2008, when I try to create a command for searching a record I got exception that said "Invalid Column name"
this is my code :
void cari()
{
koneksi.Open();
DataTable dt = new DataTable();
SqlDataAdapter SDA = new SqlDataAdapter("SELECT * FROM jadwalkuliah where Subject = "+ textBox1.Text, koneksi);
SDA.Fill(dt);
koneksi.Close();
dataGridView1.DataSource = dt;
}`
the search command should be work as search engine, can anyone help me?
Well the immediate problem is that your WHERE clause will look something like:
where Subject = Foo
which is trying to compare the value of the Subject column with the value of the Foo column.
The hacky way of fixing this is to put quotes round the value. The better solution is to use parameterized SQL:
string sql = "SELECT * FROM jadwalkuliah where Subject = #Subject";
using (SqlConnection connection = new SqlConnection(...))
using (SqlDataAdapter adapter = new SqlDataAdapter(sql, connection))
{
connection.Open();
adapter.SelectCommand.Parameters.Add("#Subject", SqlDbType.VarChar)
.Value = textBox1.Text;
adapter.Fill(dt);
}
Additionally, note that you shouldn't be performing database accesses from a GUI thread. It's not clear whether this is a web app (in which case it's okay) or WPF/WinForms (in which case it's not).
Note that that will still try to make an exact match. For a "wildcard" match you'll need to change it to something like:
SELECT * FROM jadwalkuliah where Subject LIKE #Subject
... and add the parameter with something like "%" + textBox1.Text + "%". (You'll need to then think about escaping within that value, but that's another matter...)
You haven't quoted the value of subject:
SqlDataAdapter SDA = new SqlDataAdapter("SELECT * FROM jadwalkuliah where Subject = '"+ textBox1.Text + "'",
koneksi);
Or for a contains search:
SqlDataAdapter SDA = new SqlDataAdapter("SELECT * FROM jadwalkuliah where Subject = '%"+ textBox1.Text + "%'", koneksi);
You shouldn't build queries this way. It is susceptible to SQL injection attacks.

How does one loop through DataRow to retrieve set of related columns i.e (Param Name, Param Type, and Param Value)?

I'm working on a Generic Reporting Tool, where each report is represented by a row in Reports table in database.
Report row structure:
ReportID ReportFileName
RepParam1Name RepParam1Type RepParam1Value
RepParam2Name RepParam2Type RepParam2Value ... RepParam10
So, I need to retrieve report parameters (Name, Type, and Value) and loop through them to pass them to report?
FYI: Parameter Type: Date or String.
I'm using CrystalReport designer embedded with VS.NET 2005.
Okay, so while I don't know exactly what you are heading for, I will just give you an example of what I did and you can take it or leave it.
A few details for you. This is an example of connecting to an Access Databse, but connections to other kinds of databases are similar in their connection strings. Look up connection strings for the correct syntax.
I also have a strongly typed DataSet called currentDataSet and a table defined that is named the same and structured the same as the database type. There are other ways of accomplishing this, but this is the way I did it:
string conString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + sourceString;
string strSql1 = "SELECT * FROM ReportTable";
OleDbConnection con = new OleDbConnection(conString);
con.Open();
OleDbDataAdapter dAdapter = new OleDbDataAdapter();
dAdapter.SelectCommand = new OleDbCommand(strSql1, con);
dAdapter.Fill(currentDataSet, "ReportTable");
con.Close();
From there you can manipulate the data inside of the dataset. Again here is an example:
int reportTableCount = currentDataSet.ReportTable.Count();
int reportTableCounter = 0;
while (reportTableCounter < reportTableCount)
{
if (currentDataSet.ReportTable[reportTableCounter].RepParam1Value == "Bad data")
{
currentDataSet.ReportTable[reportTableCounter].RepParam1Value = "Good data";
}
reportTableCounter = reportTableCounter + 1;
}
From this point you can now update the data in the database with the following code:
con.Open();
dAdapter.SelectCommand = new OleDbCommand(strSql1, con);
OleDbCommandBuilder objCommandBuilder = new OleDbCommandBuilder(dAdapter);
dAdapter.Update(currentDataSet, "ReportTable");
con.Close();
Like I said, if none of this helps you, feel free to disregard it, you won't hurt my feelings :)
When you say loop through a DataRow do you mean sommething like:
DataRow drMyrow = MyTables.Rows[0];
foreach (DataColumn dc in drMyRow)
{
//do something with the column
}

Categories

Resources