unable to convert date from character string [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 7 years ago.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Improve this question
I am fetching quarterly records from sql server. The records are like total debits and credits in each quarter of year. In my sql query I have made the quarters and the year is dynamic as you can see in the code.
public List<QuarterlyExpenseList> GetExpenseDataQuarterly(string Id, string Year)
{
string SQL = "select aspnetusers.username, SUM(case when Expense.Type='credit' and (Expense.Date>='#year-01-01' and Expense.Date<='#year-03-31') then Expense.Amount else 0 end) as QuarterOneCredits,";
SQL += " SUM(case when Expense.Type='credit' and (Expense.Date>='#year-04-01' and Expense.Date<='#year-06-30') then Expense.Amount else 0 end) as QuarterTwoCredits,";
SQL += " SUM(case when Expense.Type='credit' and (Expense.Date>='#year-07-01' and Expense.Date<='#year-09-30') then Expense.Amount else 0 end) as QuarterThreeCredits,";
SQL += " SUM(case when Expense.Type='credit' and (Expense.Date>='#year-10-01' and Expense.Date<='#year-12-31') then Expense.Amount else 0 end) as QuarterFourCredits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>='#year-01-01' and Expense.Date<='#year-03-31') then Expense.Amount else 0 end) as QuarterOneDebits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>='#year-04-01' and Expense.Date<='#year-06-30') then Expense.Amount else 0 end) as QuarterTwoDebits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>='#year-07-01' and Expense.Date<='#year-09-30') then Expense.Amount else 0 end) as QuarterThreeDebits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>='#year-10-01' and Expense.Date<='#year-12-31') then Expense.Amount else 0 end) as QuarterFourDebits";
SQL += " from Expense inner join AspNetUsers on AspNetUsers.Id=Expense.MadeBy";
if (Id == null)
{
SQL += " group by aspnetusers.username";
}
else
{
SQL += " where Expense.MadeBy=#id group by AspNetUsers.UserName group by aspnetusers.username";
}
using (IDbConnection cn=Connection)
{
cn.Open();
List<QuarterlyExpenseList> objList = cn.Query<QuarterlyExpenseList>(SQL, new { year = Year, id = Id }).ToList();
return objList;
}
}
here I am getting an exception of Conversion failed when converting date and/or time from character string. Can somebody tell me what does it mean and how can I get rid of it

I removed the dynamic year "#year" outside character string as it is a dynamic value. When written like '#year-04-01' SQL was treating "#year" as a character string and not as a dynamic value.
Use the following code:
public List<QuarterlyExpenseList> GetExpenseDataQuarterly(string Id, string Year)
{
string SQL = "select aspnetusers.username, SUM(case when Expense.Type='credit' and (Expense.Date>=#year+'-01-01' and Expense.Date<=#year+'-03-31') then Expense.Amount else 0 end) as QuarterOneCredits,";
SQL += " SUM(case when Expense.Type='credit' and (Expense.Date>=#year+'-04-01' and Expense.Date<=#year+'-06-30') then Expense.Amount else 0 end) as QuarterTwoCredits,";
SQL += " SUM(case when Expense.Type='credit' and (Expense.Date>=#year+'-07-01' and Expense.Date<=#year+'-09-30') then Expense.Amount else 0 end) as QuarterThreeCredits,";
SQL += " SUM(case when Expense.Type='credit' and (Expense.Date>=#year+'-10-01' and Expense.Date<=#year+'-12-31') then Expense.Amount else 0 end) as QuarterFourCredits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>=#year+'-01-01' and Expense.Date<=#year+'-03-31') then Expense.Amount else 0 end) as QuarterOneDebits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>=#year+'-04-01' and Expense.Date<=#year+'-06-30') then Expense.Amount else 0 end) as QuarterTwoDebits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>=#year+'-07-01' and Expense.Date<=#year+'-09-30') then Expense.Amount else 0 end) as QuarterThreeDebits,";
SQL += " SUM(case when Expense.Type='debit' and (Expense.Date>=#year+'-10-01' and Expense.Date<=#year+'-12-31') then Expense.Amount else 0 end) as QuarterFourDebits";
SQL += " from Expense inner join AspNetUsers on AspNetUsers.Id=Expense.MadeBy";
if (Id == null)
{
SQL += " group by aspnetusers.username";
}
else
{
SQL += " where Expense.MadeBy=#id group by AspNetUsers.UserName group by aspnetusers.username";
}
using (IDbConnection cn=Connection)
{
cn.Open();
List<QuarterlyExpenseList> objList = cn.Query<QuarterlyExpenseList>(SQL, new { year = Year, id = Id }).ToList();
return objList;
}
}

Related

SqliteDataReader DataTable.Load reads only one row when reading view

I am trying to fill a DataTable reading a view using SqliteDataReader. The following code works when I am reading a Table (not a view)
private DataTable ReadDataTable(SqliteCommand command)
{
DataTable result = new();
using (var connection = Connection)
{
connection.Open();
SqliteDataReader reader = command.ExecuteReader();
result.Load(reader);
}
return result;
}
However, when the table in question is a view, containing multiple rows, the resulting table only contains one row. To test I tried the following function, running the same command
private int ReadDataTableTest(SqliteCommand command)
{
int result = 0;
using (var connection = Connection)
{
connection.Open();
SqliteDataReader reader = command.ExecuteReader();
while(reader.Read())
result++;
}
return result;
}
This returned 6, the correct answer. Also, querying the table directly in SqliteStudio gives the right answer. The top function seems only to insert the last row of the reader in the DataTable. What is going on here?
Btw, I don't know for sure that the issue is that the table is a view, but I have a similar issue with many other views, and the "view/table" thing seems to be the common denominator.
I am using Windows, coding in .net6. using the following imports
using Microsoft.Data.Sqlite;
using System.Data;
EDIT
I am creating the command like this
private SqliteCommand CreateCommand(string tableName, DateTime reportDate)
{
var command = Connection.CreateCommand();
command.CommandText = #$"SELECT * FROM {tableName} WHERE ReportDate = $reportDate";
command.Parameters.AddWithValue("$reportDate", reportDate.ToSqliteDate());
return command;
}
And calling the code like this
var reportDate = new DateTime(2022, 7, 31);
var table = ReadDataTable(CreateCommand("MyTable", reportDate));
I am not doing anything to the table after the call.
EDIT 2
The following query generates the view
SELECT [of].ReportDate,
[of].Entity,
SUM(CASE WHEN [of].Item IN ('Equity') THEN [of].Value / fx.FxRate ELSE 0 END) AS EquityLocal,
SUM(CASE WHEN [of].Item IN ('AdjIFRS') THEN [of].Value / fx.FxRate ELSE 0 END) AS AdjIFRSLocal,
SUM(CASE WHEN [of].Item IN ('AdjIFRSGroup') THEN [of].Value / fx.FxRate ELSE 0 END) AS AdjIFRSGroup,
SUM(CASE WHEN Entity != 'Holding' AND
[of].Item IN ('Equity', 'AdjIFRS', 'AdjIFRSGroup') THEN -[of].Value / fx.FxRate ELSE 0 END) AS Elimination,
SUM(CASE WHEN Entity = 'Holding' AND
[of].Item IN ('Equity', 'AdjIFRS', 'AdjIFRSGroup') THEN [of].Value / fx.FxRate ELSE 0 END) AS EquityIFRS,
'EUR' AS ReportCurrency
FROM InputOwnFunds AS [of]
JOIN InputEurFxRates AS fx
ON [of].ReportDate = fx.ReportDate AND
[of].ReportCurrency = fx.ReportCurrency
WHERE of.Item in ('Equity', 'AdjIFRS', 'AdjIFRSGroup')
GROUP BY [of].ReportDate,
[of].Entity
UNION
SELECT [of].ReportDate,
'NLP Group' as Entity,
SUM(CASE WHEN [of].Item IN ('Equity') THEN [of].Value / fx.FxRate ELSE 0 END) AS EquityLocal,
SUM(CASE WHEN [of].Item IN ('AdjIFRS') THEN [of].Value / fx.FxRate ELSE 0 END) AS AdjIFRSLocal,
SUM(CASE WHEN [of].Item IN ('AdjIFRSGroup') THEN [of].Value / fx.FxRate ELSE 0 END) AS AdjIFRSGroup,
SUM(CASE WHEN Entity != 'Holding' AND
[of].Item IN ('Equity', 'AdjIFRS', 'AdjIFRSGroup') THEN -[of].Value / fx.FxRate ELSE 0 END) AS Elimination,
SUM(CASE WHEN Entity = 'Holding' AND
[of].Item IN ('Equity', 'AdjIFRS', 'AdjIFRSGroup') THEN [of].Value / fx.FxRate ELSE 0 END) AS EquityIFRS,
'EUR' AS ReportCurrency
FROM InputOwnFunds AS [of]
JOIN InputEurFxRates AS fx
ON [of].ReportDate = fx.ReportDate AND
[of].ReportCurrency = fx.ReportCurrency
WHERE of.Item in ('Equity', 'AdjIFRS', 'AdjIFRSGroup')
GROUP BY [of].ReportDate

InvalidArgument=Value of '1' is not valid for 'index'

I have an error in my C# application that interacts with MDB access DB.
The error is:
InvalidArgument=Value of '1' is not valid for 'index'.
My code:
objConn.Open();
listView1.Items.Clear();
OleDbCommand cmd = new OleDbCommand("select a.bill_Id,a.bill_Number,a.bill_Date,c.sup_Name,Sum(b.de_NetPrice),a.bill_Note from (suppliers c right JOIN bills a on c.sup_Id = a.bill_From) LEFT JOIN bill_Details b on a.bill_Id = b.bill_Id where a.bill_Id like '%" + txbSearch.Text + "%' or a.bill_Number like '%" + txbSearch.Text + "%' or c.sup_Name like '%" + txbSearch.Text + "%' or a.bill_Note like '%" + txbSearch.Text + "%' group by a.bill_Id,a.bill_Number,a.bill_Date,c.sup_Name,a.bill_Note order by a.bill_Date desc", objConn);
OleDbDataReader dataReader = cmd.ExecuteReader();
int i = 0;
while (dataReader.Read())
{
DateTime dt0 = DateTime.Parse(dataReader.GetValue(2).ToString());
int Date1 = DateTime.Compare(DateTime.Parse(dt0.ToShortDateString()), DateTime.Parse(txbFrom.Value.ToShortDateString()));
int Date2 = DateTime.Compare(DateTime.Parse(dt0.ToShortDateString()), DateTime.Parse(txbTo.Value.ToShortDateString()));
if (Date1 >= 0 && Date2 <= 0)
{
listView1.Items.Add(dataReader.GetValue(0).ToString());
// The error happens on the following line
listView1.Items[i].SubItems.Add(dataReader.GetValue(1).ToString());
listView1.Items[i].SubItems.Add(dt0.ToShortDateString());
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(3) ? "0" : dataReader.GetString(3));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(4) ? "0" : dataReader.GetDouble(4).ToString("n2"));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(5) ? "-" : dataReader.GetString(5));
}
i++;
}
objConn.Close();
The listview has these columns:
ID -- Number -- BillDate -- Supplier -- total -- Note
I may have found the issue.
If first time around the 'if (Date1 >= 0 && Date2 <= 0)' statemant evaluates to false, the i index will still get incremented. And then on the second iteration the if statement might evaluate to true, and then your index will be off-by-one, as there is just one Item in the ListView, but you try to get at using listView1.Items[1], instead of listView1.Items[0], which would be correct.
Solution would be to change the code to:
if (Date1 >= 0 && Date2 <= 0)
{
listView1.Items.Add(dataReader.GetValue(0).ToString());
listView1.Items[i].SubItems.Add(dataReader.GetValue(1).ToString());// The error appears on this line
listView1.Items[i].SubItems.Add(dt0.ToShortDateString());
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(3) ? "0" : dataReader.GetString(3));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(4) ? "0" : dataReader.GetDouble(4).ToString("n2"));
listView1.Items[i].SubItems.Add(dataReader.IsDBNull(5) ? "-" : dataReader.GetString(5));
i++;
}

SQL Server & C# Stored Procedure & Divide by Zero Exception

So first here is my C# code and then comes the stored procedure.
public DataTable GetCourseHighPass(String tmpCourse)
{
command.Connection = OpenConnection();
try
{
command.CommandText = "exec GetCourseCompletions #tmpCourse = '" + tmpCourse + "'";
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
dataAdapter.Fill(dataTable);
return dataTable;
}
catch (Exception)
{
throw new Exception("There are no VG's for this course.");
}
finally
{
command.Connection.Close();
}
}
And here is my stored procedure.
create procedure GetCourseCompletions
#tmpCourse nvarchar(30)
as
select (count(pnr) * 100 / (select count(pnr)
from HasStudied
where courseCode = #tmpCourse
and count(pnr) =)) as VGPrecentage
from HasStudied
where grade >= 5
and courseCode = #tmpCourse
go
The problem is that if there are no students with a high pass I will get a divide by zero exception. Looking for suggestions on how to catch this exception so the program does not crash or even better to re-write the stored procedure so it does not get an exception in the first place.
Thank you for your assistance!
Do what Eric said:
DECLARE #count int
Set #count = (select count(pnr) from HasStudied where courseCode = #tmpCourse and count(pnr) =...)
IF #count = 0
BEGIN
SELECT 0 as VGPrecentage
END
ELSE
BEGIN
select (count(pnr)*100 / #count) as VGPrecentage from HasStudied where grade >= 5 and courseCode = #tmpCourse
END
I suggest you to use this kind of query instead of yours that will handle NULL values and Zero values:
SELECT
CASE WHEN part * total <> 0 THEN part * 100 / total ELSE 0 END
FROM (
SELECT SUM(CASE WHEN grade > 5 THEN 1.00 ELSE 0.00 END) As part, SUM(1.00) as total
FROM HasStudied
WHERE courseCode = #tmpCourse) t

How to get 30 days from today including the month january

My sql table contains date of birth of many people.dates are in mm/dd/yyyy format. I want select the persons details whose birth day in next 30days. And i use the following query for that,
SELECT Mem_FirstNA, Mem_LastNA, Mem_DOB FROM MemberDetails WHERE
ltrim(str(year(GETDATE()))) + -' + ltrim(str(month(Mem_DOB))) + '-' +
ltrim(str(day(Mem_DOB))) >= getdate() - 1 AND
ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' +
ltrim(str(day(Mem_DOB))) <= getdate() + 30
And full code is
public List<MemberData> GetThisMonthBirthday()
{
List<MemberData> MD = new List<MemberData>();
using (SqlConnection con = new SqlConnection(Config.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("SELECT Mem_FirstNA, Mem_LastNA, Mem_DOB FROM MemberDetails WHERE ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' + ltrim(str(day(Mem_DOB))) >= getdate() - 1 AND ltrim(str(year(GETDATE()))) + '-' + ltrim(str(month(Mem_DOB))) + '-' + ltrim(str(day(Mem_DOB))) <= getdate() + 30", con))
{
try
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
MemberData mb = new MemberData();
mb.Mem_NA = (string)reader["Mem_FirstNA"];
mb.Mem_LastNA =(string)reader["Mem_LastNA"];
mb.Mem_DOB = (Convert.ToDateTime(reader["Mem_DOB"]));
MD.Add(mb);
}
}
catch (Exception e) { throw e; }
finally { if (con.State == System.Data.ConnectionState.Open) con.Close(); }
return MD;
}
}
The problem is that this check only till December 31, if the persons birthday in 01/01/1987 , the query is not selected that details. Please help me to solve this problem. Thank you
There are lots of ways to do this, you need conditional logic depending on whether or not you are within 30 days of the end of the year. If you're using SQL Server, I'd wrap the logic in a function to make it more readable, e.g.:
CREATE FUNCTION [dbo].[IsBirthdayInRange]
(
#Birthday DATETIME,
#StartDate DATETIME,
#EndDate DATETIME
)
RETURNS BIT
AS
BEGIN
DECLARE #StartMonthDay INT
DECLARE #EndMonthDay INT
DECLARE #BirthdayMonthDay INT
SET #StartMonthDay = MONTH(#StartDate) * 100 + DAY(#StartDate)
SET #EndMonthDay = MONTH(#EndDate) * 100 + DAY(#EndDate)
SET #BirthdayMonthDay = MONTH(#Birthday) * 100 + DAY(#Birthday)
IF YEAR(#StartDate) <> YEAR(#EndDate)
BEGIN
IF #BirthdayMonthDay >= #StartMonthDay OR #BirthdayMonthDay <= #EndMonthDay
BEGIN
RETURN 1
END
END
ELSE
BEGIN
IF #BirthdayMonthDay >= #StartMonthDay AND #BirthdayMonthDay <= #EndMonthDay
BEGIN
RETURN 1
END
END
RETURN 0
END
You can then use it as:
...
WHERE IsBirthdayInRange(Mem_DOB, GETDATE(), GETDATE() + 30)

How do I write this logic of C#'s datetime difference in SQL Server?

I have this logic in my C# code which gives me time difference between two times
Example inputs are: '12:00 AM' - '11:15 AM' gives 45 minutes.
DateTime startTime = Convert.ToDateTime(startTimeHH + ":" + startTimeMM + " " + startTimeAMPM);
DateTime endTime = Convert.ToDateTime(endTimeHH + ":" + endTimeMM + " " + endTimeAMPM);
DateTime breakTime = Convert.ToDateTime(breakTimeHH + ":" + breakTimeMM);
TimeSpan hours = endTime.Subtract(startTime);
hours = hours.Subtract(breakTime.TimeOfDay);
I referred some MSDN docs datetime functions in SQL server but couldn't find these functions which can give me time from input as 12:00 PM
However now I need to move this piece now into SQL server. How do I write it?
Example inputs are: '12:00 AM' - '11:15 AM' won't return 45 it will return 75 (it contains 15 as 25)
Here is one way to get what looks like a .NET TimeSpan:
declare #startTimeHH char(2) = '10',
#startTimeMM char(2) = '30',
#startTimeAMPM char(2) = 'AM',
#endTimeHH char(2) = '12',
#endTimeMM char(2) = '00',
#endTimeAMPM char(2) = 'PM',
#breakTimeHH char(2) = '01',
#breakTimeMM char(2) = '15',
#startTime DateTime,
#endTime DateTime,
#breakTime DateTime,
#result Time
set #startTime = cast ((#startTimeHH + ':' + #startTimeMM + ' ' + #startTimeAMPM) as Time);
set #endTime = cast ((#endTimeHH + ':' + #endTimeMM + ' ' + #endTimeAMPM) as Time);
set #breakTime = cast ((#breakTimeHH + ':' + #breakTimeMM) as Time);
set #result = #endTime - #startTime - #breakTime
select cast(#result as CHAR(8))
The result is 00:15:00
CREATE TABLE [dbo].#events (
[StartTime] time NULL,
[EndTime] time NULL )
INSERT INTO #events
VALUES
('08:00', '08:30'),
('08:30', '08:00'),
('09:00', '10:00'),
('15:00', '16:30')
select convert(time, dateadd(minute, datediff(minute, StartTime, EndTime), 0))
From #events
drop table #events
ResultSet
00:30:00.0000000
23:30:00.0000000
01:00:00.0000000
01:30:00.0000000
Use DateDiff function
DatePart will be handy, too
Here is some SQL that returns '45' (minutes)
DECLARE #Start DATETIME, #END DATETIME
SET #Start = '2009-05-02 10:00:50'
set #End = '2009-05-02 10:45:50'
-- FYI
SELECT #start, #end
-- returns 45
SELECT DateDiff(mi, #start, #end)

Categories