How to get year from string date c# - sql

I have string date in sql server, and I want to retrieve all the rows greater than or equal the year of 2018 using ADO.Net. This is what I've accomplished but the result.HasRows() returns false although I already have rows in that table.
Is it something related to Culture?
UPDATE:
the problem was in data itself. there were some date in different format. it works now.
using (var command = connection.CreateCommand())
{
command.CommandText = $"SELECT *
$"FROM [dbo].[tableName] " +
$"WHERE Year(CAST([tableNmae].Date as datetime)) >= {2018} ";
using (var result = command.ExecuteReader())
{
if (result.HasRows)
{
while (result.Read())
{}
}
}
}

You cannot use CAST for the string type. You should use CONVERT instead of CAST
Why 104? Because I took this website as a reference.
http://www.sqlusa.com/bestpractices/datetimeconversion/
using (var command = connection.CreateCommand())
{
command.CommandText = $"SELECT *
$"FROM [dbo].[tableName] " +
$"WHERE Year(CONVERT(DATETIME,[tableNmae].Date,104)) >= {2018} ";
using (var result = command.ExecuteReader())
{
if (result.HasRows)
{
while (result.Read())
{}
}
}
}
NOTE: To use CONVERT, the column must not be of ntext type.
If you use it you will get this error.
Explicit conversion from data type ntext to datetime is not allowed.
Sample error if you don't use the correct dial type

Related

How to insert multiple integer parameters into query?

Website user can enter search criteria to query orders. User, States, Status, OrderID, etc.
Website communicates with API. Query parameters are in the header, so I assume they come in as strings. API communicates with Access via Dapper.
For some criteria, they can send multiple values. So I want to use an "IN" clause.
where UserID in (150, 3303, 16547)
Dapper handles this nicely.
connection.Query<int>("select * from table where Id in #Ids", new { Ids = new int[] { 1, 2, 3 } });
This works in MS-Access
SELECT top 100 * from Orders where UserID in (150, 30330)
But that only works when the values are ints. String and Strings both give "Data type mismatch in criteria expression" in Access.
SELECT top 100 * from Orders where UserID in ("150", "30330") // two strings
SELECT top 100 * from Orders where UserID in ("150, 30330") // single string
It may be a coincidence, but all the examples I see are integers. Access throws an error on strings if you don't specify the size. Using DynamicParameters makes it easy to specify the size.
But when the field is an int, my dapper code gives the same error (Data type mismatch in criteria expression):
var paramlist = new DynamicParameters();
if ((!string.IsNullOrWhiteSpace(userId)) && userId != "0") {
paramlist.Add("userId", userId, DbType.String, ParameterDirection.Input, 50);
sbWhere.AppendFormat("AND CustFID in (?) ", paramIndex++);
}
So I assume the issue is that I'm telling it that the parameter is a string.
But if I make the parameter an int, then it won't take the string with multiple values. Conversely, if I include the () in the string, it complains about the parens being missing from the 'in' clause.
I tried splitting the string of numbers into an array and/or list.
if ((!string.IsNullOrWhiteSpace(userId)) && userId != "0") {
var userIds = userId.Split(','); //.ToList(); fails, can't map to native type
paramlist.Add("userId", userIds, DbType.String, ParameterDirection.Input, 1000);
if (userIds.Length > 1) {
sbWhere.AppendFormat("AND CustFID in #userId ", paramIndex++);
} else {
sbWhere.AppendFormat("AND CustFID = #userId ", paramIndex++);
}
}
and it gives ": No mapping exists from object type System.String[] to a known managed provider native type." whether I say the parameters are int32 or string.
UPDATE:
There may be multiple search criteria, so I'm using DynamicParameters.
Here is my attempt at implementing Palle Due's idea.
if ((!string.IsNullOrWhiteSpace(userId)) && userId != "0") {
// var userIds = userId.Split(',').Select(i => Int32.Parse(i)).ToList();// fails, can't map to native type
IEnumerable<int> userIds = userId.Split(',').Select<string, int>(int.Parse);
paramlist.Add("userId", userIds, DbType.Int32, ParameterDirection.Input);
if (userIds.Count() > 1) {
sbWhere.AppendFormat("AND CustFID in #userId ", paramIndex++);
} else {
sbWhere.AppendFormat("AND CustFID = #userId ", paramIndex++);
}
}
using (IDbConnection conn = Connection) {
string sQuery = string.Format("SELECT {0} FROM vwweb_Orders {1}", columns, where);
conn.Open();
var result = await conn.QueryAsync<Order>(sQuery, paramlist);
return result.ToList();
}
throws
Message: System.AggregateException : One or more errors occurred. (Failed to convert parameter value from a SelectArrayIterator`2 to a Int32.)
----> System.InvalidCastException : Failed to convert parameter value from a SelectArrayIterator`2 to a Int32.
----> System.InvalidCastException : Object must implement IConvertible.
The github page #Dai links to specifies that the Dapper list support only works with IEnumerable<int>.
But as I understand it your UserID is an int, so I don't get why you try to enter a string. You need to get the string the user has input and convert it to IEnumerable<int>. Do something like this:
IEnumerable<int> userIDs = (userId?? "").Split(',').Select<string, int>(int.Parse);
var result = connection.Query<int>("SELECT TOP 100 * FROM Orders WHERE UserID IN #Ids", new { Ids = userIDs });
You might want to apply some input checking to that, and you might also want to reconsider using Access as the "database" for a website. It's not what it was meant for.
I give up. Dapper should be able to handle this, but it's a newer feature, so...
I just built the IN clause myself.
if (userIds.Count() > 1) {
sbWhere.AppendFormat("AND CustFID in ( ");
int paramCnt = 0;
foreach (int id in userIds) {
sbWhere.AppendFormat("?, "); // Access doesn't mind a trailing ,
paramlist.Add("userId" + paramCnt.ToString(), id, DbType.Int32, ParameterDirection.Input);
paramCnt++;
}
sbWhere.AppendFormat(") ");
} else {
sbWhere.AppendFormat("AND CustFID = ? ");
paramlist.Add("userId", userIds.ToArray<int>()[0], DbType.Int32, ParameterDirection.Input);
}

How to convert values of a datatable from string to integer

I'm making a fine calculator in a library system. In it,I need to calculate the fine of a given day. For this,I use a data table to load the fine amounts and then,I need to calculate the total fine amount by adding each fine amount.But I'm having a problem in parsing the fine values which are in string format to integer.Here is a screenshot of the error.
Here is a screenshot of the error.
And here is the code which I used to convert the string values to integer and calculate the total fine.
int sum1 = 0;
int myNum;
String Display;
private void btnNext_Click(object sender, EventArgs e)
{
try
{
if (rbtnToday.Checked == true)
{
DateTime today = DateTime.Today;
Con.Open();
String select_today_query = "SELECT Fine FROM BookReceiveMem WHERE RecDate='" + today + "'";
Sqlda = new SqlDataAdapter(select_today_query, Con);
DataTable Dt = new DataTable();
Sqlda.Fill(Dt);
Con.Close();
foreach (DataRow row in Dt.Rows)
{
myNum = int.Parse(Dt.Columns[0].ToString());
sum1 = sum1 + myNum;
}
Display = sum1.ToString();
MessageBox.Show("Today Fine Amount is= " + Display, "Today Fine Calculation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
Is there any method to solve this problem?
Databases are really good at calculating things like a sum. If Fine is an integer in your database you can get it to sum all the rows and just return that:
SELECT SUM(Fine) As TotalFine
FROM BookReceiveMem
WHERE RecDate = #recDate
Which you could call from code without ever needing a DataTable as follows:
using(var cmd = Con.CreatCommand())
{
cmd.CommandText = "SELECT SUM(Fine) As TotalFine FROM BookReceiveMem WHERE RecDate = #recDate";
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#recDate",DateTime.Today);
var result = (int)cmd.ExecuteScalar();
MessageBox.Show("Today Fine Amount is= " + result, "Today Fine Calculation", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Note that the above uses a Parameterized Query which is much safer than using string concatenation
However, a more direct answer to your question:
myNum = int.Parse(Dt.Columns[0].ToString());
Here you're getting the Column and trying to turn that to an integer. What you actually meant to do was get the row value (and you dont need to Parse it - it's already an integer!)
myNum = (int)row["Fine"];

Store date and time in sql server 2012 using c#

i want to store date and time in SQL Server 2012 using asp.net but generate some error "Conversion failed when converting date and/or time from character string."
protected void btn Submit_Click(object sender, EventArgs e)
{
lbldate.Text = Convert.ToDateTime(this.txtdate.Text).ToString("dd/MM/yyyy");
lbltime.Text = Convert.ToDateTime(this.txttime.Text).ToLongTimeString();
TimeSpan time = new TimeSpan();
time.ToString();
SqlConnection con = new SqlConnection(#"Data Source=DESKTOP-O6SE533;Initial Catalog=Datertime;Integrated Security=True;Connect Timeout=15;Encrypt=False;TrustServerCertificate=False");
SqlCommand cmd = new SqlCommand("insert date,time into DateTimedemo values('" +txtdate.Text + "','"+txttime.Text+"')", con);
con.Open();
int r = cmd.ExecuteNonQuery();
if (r > 0)
{
Response.Write("success");
}
else
{
Response.Write("failed");
}
}
Use parameterized SQL instead of building the SQL dynamically. This avoids SQL injection attacks and string formatting differences, as well as making the code clearer.
Additionally, I believe both "date" and "time" are keywords in T-SQL, so you should put them in square brackets when using them as field names.
You should attempt to perform as few string conversions as possible. Without knowing exactly what your web page looks like it's hard to know exactly how you want to parse the text, but assuming that Convert.ToDateTime is working for you (sounds worryingly culture-dependent to me) you'd have code like this:
protected void btn Submit_Click(object sender, EventArgs e)
{
// TODO: Ideally use a date/time picker etc.
DateTime date = Convert.ToDateTime(txtdate.Text);
DateTime time = Convert.ToDateTime(txttime.Text);
// You'd probably want to get the connection string dynamically, or at least have
// it in a shared constant somewhere.
using (var con = new SqlConnection(connectionString))
{
string sql = "insert [date], [time] into DateTimeDemo values (#date, #time)";
using (var cmd = new SqlCommand(sql))
{
cmd.Parameters.Add("#date", SqlDbType.Date).Value = date;
cmd.Parameters.Add("#time", SqlDbType.Time).Value = time.TimeOfDay;
int rows = cmd.ExecuteNonQuery();
string message = rows > 0 ? "success" : "failed";
Response.Write(message);
}
}
}
I've guessed at what SQL types you're using. If these are meant to represent a combined date and time, you should at least consider using a single field of type DateTime2 instead of separate fields.

System.Data.SqlClient.SqlException: Incorrect syntax near '2017-03-21'

protected void btnBeds_click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString);
con.Open();
String checkBeds = "SELECT Count (*) FROM Bed WHERE bedID NOT IN (SELECT DISTINCT(bedID) FROM Booking where startDate>='"+TxtArrivalDate.Text+"' and endDate<= '"+txtDepartureDate.Text+"'";
SqlCommand showcheckBeds = new SqlCommand(checkBeds, con);
ResultLabel.Text = showcheckBeds.ExecuteScalar().ToString();
con.Close();
}
I'm trying to display the amount of free beds there are in the database and im getting this error.
Always use parameters in your queries
Always wrap connections and other types that implement IDisposable in using statements to ensure the resource is released
Use the correct types in your database and match that type with the passed in parameter. Example: do not pass in a string for a date, do not store dates as strings.
Your actual problem was a missing ) at the end of your sql statement as pointed out by #Damien_The_Unbeliever
Updated code with changes:
const string checkBeds = "SELECT Count (*) FROM Bed WHERE bedID NOT IN (SELECT DISTINCT(bedID) FROM Booking where startDate >= #startDate and endDate<= #endDate)";
using(SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString))
using(SqlCommand showcheckBeds = new SqlCommand(checkBeds, con))
{
showcheckBeds.Parameters.Add(new SqlParameter("#startDate", SqlDbType.DateTime){Value = DateTime.Parse(TxtArrivalDate.Text) });
showcheckBeds.Parameters.Add(new SqlParameter("#endDate", SqlDbType.DateTime){Value = DateTime.Parse(txtDepartureDate.Text) });
con.Open();
ResultLabel.Text = showcheckBeds.ExecuteScalar().ToString();
}
Note: In the code above I used a direct DateTime.Parse to get an actual DateTime instance to pass as a parameter. It would probably be advisable to change that either to ParseExact or to provide a CultureInfo instance to the method.
Try This
String checkBeds = "SELECT Count (*) FROM Bed WHERE bedID NOT IN (SELECT DISTINCT(bedID) FROM Booking where startDate>='"+Convert.ToDateTime( TxtArrivalDate.Text).ToStrin("dd MMM yyyy")+"' and endDate<= '"+Convert.ToDateTime(txtDepartureDate.Text).ToString("dd MMM yyyy")+"'";

Error Date in SQL Query

I have a problem with my SQL query.
The error is :
The conversion of a varchar data type to a smalldatetime data type resulted in an" + " out-of-range value.
I tried to use the CONVERT function to remedy it but in vain.
public static List<string> Helper_Statistic_6(DateTime start, DateTime end) {
DateTime dateStart = start;
DateTime dateEnd = end;
string query = "SELECT ... FROM ... WHERE DATE BETWEEN CONVERT(VARCHAR(10),'" + dateStart+ "',120) and CONVERT(VARCHAR(10),'" + dateEnd+ "',120) ";
}
I suspect you're using C# with Microsoft SQL Server.
In any case, to avoid the woes of code injection, one should try to use parametized SQL. Allow the compiler take care of marshalling a C# Date to a SQL Date.
EDIT: As per #marc_s suggestion, you should beware using reserved SQL keywords as column names, otherwise, protect them from being treated as SQL keywords by using [ ] symbols, i.e. [DATE] isntead of DATE.
I would expect the syntax to look like this:
public static void Run_Helper_Statistic_6(DateTime start, DateTime end)
{
using (SqlCommand command = new SqlCommand(
"SELECT ... FROM ... WHERE [DATE] BETWEEN #start and #end", connection))
{
command.Parameters.Add(new SqlParameter("start", start));
command.Parameters.Add(new SqlParameter("end", end));
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
// ...
}
}
}