C# Select in SQL Server just using the Date with sql parameters - c#

I am currently trying to do a Select in my SQL Server database using a parameter with Datetime type. But I need this parameter only has the format YYYY-MM-DD date because of the following query in SQL I'm using and it's working :
select
idCliente, DescCliente, DescAnalista , StatusChamado , DataAtendimento
from
Atendimento
where
cast ([DataAtendimento] as date) = '2016-04-27';
I read several posts indicating that I use DbType or .ToString but when running it is generating error alleging failure to convert the string to the date / time format.
This is how I use the SqlParameter:
DateTime date;
date = Data;
try
{
sqlClient.Command.Parameters.AddWithValue("#adate", date);
sqlClient.Command.CommandText = #" select idCliente, DescCliente, DescAnalista , StatusChamado , DataAtendimento from Atendimento where cast ([DataAtendimento] as date) = '#adate';";
I need a help from you guys , I'm not finding any means that can perform this select

You have to remove the '' in = '#adate'. With the '' in place, it effectively turns your query into:
select
idCliente, DescCliente, DescAnalista , StatusChamado , DataAtendimento
from Atendimento
where cast ([DataAtendimento] as date) = '#date';
This means that cast([DateAtendimento] as date) is compared against the string '#date', thus the conversion to date error.

Related

Receiving ORA-0858 in Oracle DataReader but not in SQL Developer

I have a query that was built and works using SQL Developer. When I use the same query in an Oracle DataReader object, I receive ORA-01858: a non-numeric character was found where a numeric was expected
If I remove the clause to check the CRTDDATE column, the query works in the DataReader.
query:
SELECT count(distinct(H.id)) AS Completed, T.Cat, 'Task' as Type
FROM HISTORY H
INNER JOIN Tasks T ON H.id = T.id
WHERE H.Step In ('1.41', '1.61', '6.41', '6.61')
AND T.Cat = :cat
and H.CRTDDATE >= :sdate and H.CRTDDATE <= :edate
GROUP BY T.Cat, 'Task'
Code:
using (OracleConnection conn = new OracleConnection(ConnectionString))
{
OracleCommand cmd = new OracleCommand(query, conn);
cmd.Parameters.Add("sdate", startDate);
cmd.Parameters.Add("edate", endDate);
cmd.Parameters.Add("cat", cat);
await conn.OpenAsync();
using (var dr = await cmd.ExecuteReaderAsync())
{
if (dr.HasRows)
{
while (await dr.ReadAsync())
{
var report = new IPTCompletedReport();
var count = dr.GetString(0);
report.Completed = 0;
report.IPT = dr.GetString(1);
report.Type = dr.GetString(2);
results.Add(report);
}
}
}
}
Values:
startDate = {1/1/2021 12:00:00 AM}
endDate = {8/17/2022 12:00:00 AM}
cat = "DRV"
The error occurs at this line: using (var dr = await cmd.ExecuteReaderAsync())
How can I change the query to allow the DataReader to accept it?
Should I use a DataAdapter instead?
I have several other queries and DataReaders in this file that are functioning properly. Most of them have where clauses featuring date checks.
I don't know C# nor DataReader, but - error you got (and found line that causes it):
and H.CRTDDATE >= :sdate and H.CRTDDATE <= :edate
means that Oracle - in DataReader - can't implicitly convert values you provided as :sdate and :edate into a valid DATE datatype value. Oracle SQL Developer, on the other hand, did it and query worked.
Let me illustrate the problem.
Test table with one column whose datatype is DATE; as sysdate function returns value of that datatype, insert works OK:
SQL> create table test (datum date);
Table created.
SQL> insert into test values (sysdate);
1 row created.
SQL> select * From test;
DATUM
----------
17.08.2022
Really, today is 17th of August 2022.
Let's set date format and date language:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> alter session set nls_date_language = 'croatian';
Session altered.
If I pass strings (note that '17.08.2022' is a string; to us, humans, it represents date, but Oracle has to implicitly try to convert it to date datatype:
SQL> select * from test where datum between '17.08.2022' and '20.08.2022';
DATUM
----------
17.08.2022
Oracle succeeded! Nice! OK, but - what if I pass a string that - instead of numeric month value - contains month abbreviation, written in English (remember that I previously set date language to Croatian!):
SQL> select * from test where datum between '17-aug-2022' and '20-aug-2022';
select * from test where datum between '17-aug-2022' and '20-aug-2022'
*
ERROR at line 1:
ORA-01858: a non-numeric character was found where a numeric was expected
Aha ... here's the error, the same as you got. Oracle wasn't able to implicitly convert string '17-aug-2022' into date datatype value.
What if I pass Croatian month name (it is "kolovoz" for "August"):
SQL> select * from test where datum between '17-kol-2022' and '20-kol-2022';
DATUM
----------
17.08.2022
SQL>
Right, not it works again.
So, what should you do? Take control over it! One option is to use to_date function with appropriate format model. I'll again pass English month name, but this time it'll be OK:
SQL> select * from test where datum between to_date('17-aug-2022', 'dd-mon-yyyy', 'nls_date_language = english')
2 and to_date('20-aug-2022', 'dd-mon-yyyy', 'nls_date_language = english');
DATUM
----------
17.08.2022
SQL>
Or, if you don't want to use that, use date literal (which always consists of the date keyword followed by date value in yyyy-mm-dd format enclosed into single quotes):
SQL> select * from test where datum between date '2022-08-17' and date '2022-08-20';
DATUM
----------
17.08.2022
SQL>
If you can't do any of these, then make sure that you passed values which can be implicitly converted to date datatype value.
Unfortunately, as I said, I don't know C# so I can't suggest anything smart (related to C#), but I hope that now - that you know what caused the error - you'll be able to fix it.
Using the comment from #madreflection, I added cmd.BindByName = true and that fixed my problem.
Thanks to everyone who provided suggestions.

How to pass date time format in dapper parameter for postgresSQL?

For a query on a table in PostgreSQL I am able to fetch data correctly.
var query = "Select Id,name from employee
where
joiningTime BETWEEN '{startDateTime:yyyy-MM-dd HH:mm:ss}' AND '{endDateTime:yyyy-MM-dd HH:mm:ss}'"
The data are returned correctly but since this approach is prone for SQL Injection, I want to change this to parameterized way
var query = "Select Id,name from employee
where
joiningTime BETWEEN '#startDateTime' AND '#endDateTime'"
var result = dbConnection.Query<Result>(query, new {startDateTime, endDateTime });
How can the format be passed still with parameters?
DateTimes don't have a format, they're like number (eg like 1000 can be formatted as 1000.0 or 1x10^3 etc but it's still just a thousand).
You just write the query like:
SELECT * FROM t WHERE dateCol BETWEEN #fromDate AND #toDate
Note: you don't put ' around parameter names!
And in the dapper call you put datetime typed parameters:
DateTime x = DateTime.Now.AddDays(-1);
DateTime y = DateTime.Now;
dbConnection.Query<Result>(query, new { fromDate = x, toDate = y});
If, in your database, you've made your datetime columns varchar and filled them with strings that's the first thing you should fix (make them a proper date type)..
But even if you did dothis, the advice wouldn't change:
DateTime x = DateTime.Now.AddDays(-1);
DateTime y = DateTime.Now;
dbConnection.Query<Result>(
"SELECT * FROM t WHERE dateCol BETWEEN #fromDate AND #toDate",
new {
fromDate = x.ToString("yyyy-MM-dd HH:mm:ss"),
toDate = y.ToString("yyyy-MM-dd HH:mm:ss")
}
);
You're still writing parametyers into your SQL, you're now putting formatted strings into the parameter values to match the formatted strings in the DB table. Don't do this if your table holds DATE/TIME/TIMESTAMP type columns - this is only for if you've arrange the questionable(foolish)_ situation of storing your dates as strings and are unwilling to change it (you should)

How to add parameters in a SQL select query?

How to add parameters in a SQL select query?
string time = 2013-09-25 00:00:00;
I wish to use the time variable in the below mentioned SQL query
Select LastUpdated from Employee where LastUpdated > time;
Try this:
string sqlDate = time.ToString("yyyy-MM-dd HH:mm:ss.fff");
It appears what the OP is asking is how to convert a VARCHAR to a DATETIME in SQL Server not actually a String to DateTime in C#.
You will need to use the following to convert to a DATETIME:
SELECT LastUpdated
FROM Employee
WHERE LastUpdated > CONVERT(datetime, varTime, 121);
See the following MS Reference for more information.
To echo others though, you should just pass the parameter in as a datetime and let the database provider factory handle the conversion of appropriate types, or add a new method that actually returns a DateTime. In the future, I wouldn't name a method GetUpdateTime unless it actually returns a type of Time.
You can convert your string in C# code to DateTime using
DateTime.TryParse() or Convert.ToDateTime()
OR
Convert VARCHAR to DATETIME in SQL using
Convert(datetime, time)
I just framed my question in a wrong, the query remains the same though. I just wanted time to be added as a paramter in my SQL-query. The code for the same looks like
String commandText = "Select LastUpdated from Employee where LastUpdated > :time;";
OracleConnection connection = new OracleConnection(connectionString);
OracleCommand command = new OracleCommand(commandText, connection);
command.Parameters.Add("time", time);
Thanks a lot for your help!
My bad that I couldn't frame the question properly.

SQLite - no data sqlite select with condition on datetime

I have select query in SQLite Database. There is a LogInTime field that datatime datatype.
Here is AccessDate variable passing date "11/16/2016" like format
string sql = "SELECT * FROM Tble_Login where LogInTime = '" + AccessDate + "'";
The SQLite Tble_Login looking like this,
After excute this query, no data? How can I get data?
Referring to the SQLite documentaion you should use following format for AccessDate
YYYY-MM-DDor YYYY-MM-DD HH:MM or YYYY-MM-DD HH:MM:SS. On the documentation page you can find more formats in the section Time Strings
You can also try to use the BETWEEN statement like in this question
string sql = #"SELECT * FROM Tble_Login where LogInTime BETWEEN ""2016-11-16"" AND ""2016-11-17""";

Passing C# datetime value to Oracle DB Query

I have a SQL query that I am passing a C# variable into my Oracle DB.
I am having trouble passing a C# datetime variable, "PROCESS_DATE", into my query in my application. I do not get any records back. If I copy the query into my oracle developer tool, TOAD, it works fine and I get multiple records.
Here is the query I am using in my application:
String SelectAllSQL = "SELECT * FROM REALMS_AUDIT.R2_GROUP_QUERY_RPT WHERE PROCESS_DATE = :pPROCESS_DATE";
I also tried converting the datetime variable into a shortDateString() so it matches the database exactly I then used the TO_DATE function, which I have to use if I query dates directly in TOAD, without any luck. The shortDateString() changes my date into: 1/16/2016, which is what I need, but the OracleDataReader does not like it. Here it the query with the TO_DATE function:
String SelectAllSQL = "SELECT * FROM REALMS_AUDIT.R2_GROUP_QUERY_RPT WHERE PROCESS_DATE = TO_DATE(:pPROCESS_DATE, 'MM-DD-YYYY'";
:pROCESS_DATE is a datetime variable that is passed in.
There must be a breakdown between C# and Oracle in relation to handling a datetime variable. I am using Oracle DataReader to handle the processing of the query.
OracleDataReader dataReader = mDataAccess.SelectSqlRows ( oracleConnection, oracleCommand, sqlCommand, parameters );
while ( dataReader.Read ( ) )
{
groupEntityFacilityRptList.Add ( ReadRecord ( dataReader ) );
}
If I use the TO_DATE function, the application will not step into the while loop. If I use the original query, it does but returns no data.
The datetime variable PROCESSDATE looks like this:
1/16/2016 12:00:00 AM
I notice it has a timestamp on it, so I'm not sure if that is the problem or not.
The data in Oracle is like this:
1/16/2016
Unless I've totally misunderstood your issue, I think you might be making this harder than it needs to be. ODP.net handles all of that dirty work for you. If PROCESS_DATE is an actual DATE datatype in Oracle, then you just need to pass an actual C# DateTime variable to it and let ODP.net do the heavy lifting. There is no need to do conversion of any type, provided you are passing an actual date:
DateTime testDate = new DateTime(2015, 7, 16);
OracleCommand cmd = new OracleCommand(
"SELECT * FROM REALMS_AUDIT.R2_GROUP_QUERY_RPT WHERE PROCESS_DATE = :pPROCESS_DATE",
conn);
cmd.Parameters.Add(new OracleParameter("pPROCESS_DATE", OracleDbType.Date));
cmd.Parameters[0].Value = testDate;
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
object o = reader.IsDBNull(0) ? null : reader.GetValue(0);
}
reader.Close();
If your data in C# is not a date, I'd recommend making it one before even trying:
DateTime testDate;
if (DateTime.TryParse(testDateString, out testDate))
{
// run your query
}
As per my comment, please try below and see this resolves.
TRUNC(TO_DATE(:pPROCESS_DATE,'MM-DD-YYYY HH:MI:SS AM')) if pROCESS_DATE format is 1/16/2016 12:00:00 AM.
TRUNC(TO_DATE(:pPROCESS_DATE,'DD-MM-YYYY HH:MI:SS AM')) if pROCESS_DATE format is 16/1/2016 12:00:00 AM.
First, I learned that my code will not go into the code below unless I actually have records returned to me.
OracleDataReader dataReader = mDataAccess.SelectSqlRows ( oracleConnection, oracleCommand, sqlCommand, parameters );
while ( dataReader.Read ( ) )
{
groupEntityFacilityRptList.Add ( ReadRecord ( dataReader ) );
}
Second, to get ProcessDate to work, I needed to take the string that was coming from my View, convert it to a datetime, and then I formatted it back as a string. It may not be best practices but it worked.
public JsonResult GetGroupReportData ( String reportDate )
{
DateTime processDate = DateTime.Parse ( reportDate );
var monthlyReport = SelectAllGroupRprt (processDate.ToString("MM/dd/yyyy");
return new JsonResult ( )
{
Data = monthly,
MaxJsonLength = Int32.MaxValue
};
}

Categories

Resources