I have a DateTime component in my code, and I want to use it for a query in my SQL Server database.
When inserting this component, there seems to be no problem, but when querying for smalldatetime values, I just don't know how to do it. The dataset is always empty.
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "ReadDates";
dataset = new DataSet();
SqlParameter parameter = new SqlParameter("#date", SqlDbType.SmallDateTime);
parameter.Value = DateTime.Now();
cmd.Parameters.Add(parameter);
dataAdapter = new SqlDataAdapter(cmd);
dataAdapter.Fill(dataset);
return dataset;
And this is in my stored procedure:
select * from TableDates
where ValueDate <= #date
So I have no problems running the procedure in SQL Server Management Studio, when entering a parameter in this format: '2000-03-03 04:05:01', but when passing a DateTime, the query is always empty. Any suggestions?
I tried it by using SQL Server 2008 R2 Express.
Here is the example stored procedure i wrote:
CREATE PROCEDURE [dbo].[ShowGivenSmallDateTimeValue]
#givenSmallDateTime smalldatetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Simply return the given small date time value back to sender.
SELECT #givenSmallDateTime
END
And here is the C# code to execute the procedure:
var connectionBuilder = new SqlConnectionStringBuilder();
connectionBuilder.DataSource = "localhost\\sqlexpress";
connectionBuilder.IntegratedSecurity = true;
var now = DateTime.UtcNow;
using (var connection = new SqlConnection(connectionBuilder.ConnectionString))
using (var command = new SqlCommand())
{
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "ShowGivenSmallDateTimeValue";
command.Parameters.Add(new SqlParameter("#givenSmallDateTime", SqlDbType.SmallDateTime) { Value = now });
connection.Open();
var result = (DateTime)command.ExecuteScalar();
var difference = result - now;
Console.WriteLine("Due to the smalldatetime roundings we have a difference of " + difference + ".");
}
And it simply works.
Here's my code for creating the SqlParameter for a Datetime; For SQL Server 2008 we pass the value as datetime2 since SQL will implicity convert from datetime2 to every other date type so long as it is within the range of the target type...
// Default conversion is now DateTime to datetime2. The ADO.Net default is to use datetime.
// This appears to be a safe change as any datetime parameter will accept a datetime2 so long as the value is within the
// range for a datetime. Hence this code is acceptable for both datetime and datetime2 parameters, whereas datetime is not
// (because it doesn't handle the full range of datetime2).
SqlParameter sqlParam = new SqlParameter(name, SqlDbType.DateTime2);
Since Your parameter includes zeros in day and month parts...sql server converts it but doest match to your date.... i.e.,
if DATETIME.now() returns '2000-03-03 04:05:01'... it is casted into 2000-3-3 Without including zeros...so u need to specify zeros also to match your date.
Related
I need to get an employees start date. What I am trying to do is when a check box is checked make a call to the database get the date and return it into my C# code. I think I have everything set-up close to perfect, but my call procedure returns an error. Can someone assist me with setting up syntax so that when a check box is checked it will make a call to the database, run a stored procedure, and return the result (as a datetime) from the stored procedure back into my C# syntax?
EDIT --- The error being thrown is:
cannot implicitly convert type 'System.DateTime' to 'string'
//Calling Procedure
this.txtStartDate.Text = getHireDate(Constants.Database, employeename);
//Actual Procedure
private static string getHireDate(string Database, string employeename)
{
SqlConnection connection = new SqlConnection(Database);
SqlCommand command = new SqlCommand("_uspGetHireDate", connection);
command.CommandType = CommandType.StoredProcedure;
SqlParameter returnValue = new SqlParameter("returnVal", SqlDbType.Int);
returnValue.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(returnValue);
connection.Open();
command.ExecuteNonQuery();
connection.Close();
//This line throws an error of can not implicitly convert 'System.DateTime' to 'string'
return Convert.ToDateTime(returnValue.Value);
}
//Stored Procedure Being Called
alter procedure [dbo].[_uspGetHireDate]
(
#employeename varchar(100)
)
as
declare #StartDate datetime
set NOCOUNT ON
Set #StartDate = (SELECT CONVERT(VARCHAR(10), HireDate, 101)
FROM tbl_employeeinformation
where hiredate is not null
AND active = 1
AND employeename = #employeename
return #StartDate
Your solution is totally messy. Why are you converting DATE to VARCHAR, then return it as an INT, then converting it as a DateTime and return as STRING???
First of all change your stored procedure to return value standard way. Return DATE, not INT with return:
alter procedure [dbo].[_uspGetHireDate]
#employeename varchar(100)
as
set NOCOUNT ON
SELECT HireDate
FROM tbl_employeeinformation
where hiredate is not null
AND active = 1
AND employeename = #employeename
Then change your method to return DateTime:
private static DateTime getHireDate(string Database, string employeename)
{
SqlConnection connection = new SqlConnection(Database);
SqlCommand command = new SqlCommand("_uspGetHireDate", connection);
command.CommandType = CommandType.StoredProcedure;
connection.Open();
var result = Convert.ToDateTime(command.ExecuteScalar());
connection.Close();
return result;
}
Thanks to #petelids for pointing this out. Change your presentation layer to:
this.txtStartDate.Text = getHireDate(Constants.Database, employeename).ToString("yyyy-MM-dd");
or whatever format that is appropriate. Visualizing data is a work of a presentation layer and not of a business layer. Here you are storing connection string in presentation layer and this is a bit of strange.
Also put your connections, commands etc in using blocks and use try-catch blocks.
Also I have noticed that you are not passing #employeename parameter to your stored procedure.
You are returning DateTime instead of string as intended in function return type
private static string getHireDate(string Database, string employeename)
{
----
return Convert.ToDateTime(returnValue.Value); // Here you are returning datetime but your return type should be string as your function return type is string
}
I use GETDATE() in a SQL Server stored procedure to insert a date into the SQL Server database table.
After that I need to implement a C# function which is based on datetime input parameter finds if the date was saved in the tables.
The datetime in C# and SQL are different. How do I convert from C# datetime to SQL datetime which has a form of yyyy-mm-ddT:yy:mm:ss.mmm? I need to specify explicitly yyyy-mm-ddT:yy:mm:ss.mmm.
Will be happy for all propositions/possible ways.
DateTime in .Net framework and SQL Server (if it is DateTime type field) is irrespective of the format. Format is only useful for displaying output.
If your field in SQL Server is of DateTime type then you can query it from C# code using parameterized query something like:
public DataTable GetRecords(DateTime dtParameter)
{
DataTable dt = null;
using (SqlConnection conn = new SqlConnection("connection string"))
{
using (SqlCommand cmd = new SqlCommand("SELECT * from yourTable where DateField = #dateparameter"))
{
conn.Open();
cmd.Parameters.AddWithValue("#dateparameter",dtParameter);
SqlDataReader dr = cmd.ExecuteReader();
//...rest of the code
dt.Load(dr);
}
}
return dt;
}
Datetimes between C# and SQL are 100% compatible. The format shouldn't make any difference if you are passing them as DateTimes. If you are generating a SQL string then I would highly recommend changing to SQL Parameters so you don;t have to worry about any formatting issues.
A datetime has no format at all, it has a value. SQL-DateTimes and C# DateTimes are compatible. So don't convert it (to string) at all but pass it as datetime-parameter to the database.
Then you're safe if the DateTime value is within SqlDateTime.MinValue(January 1, 1753) and SqlDateTime.MaxValue(December 31, 9999).
You should never write DateTime.Now from client code to insert into the database as this will be based on the clients local time; do this
public DateTime GetDatabaseTime()
{
var parameter = new SqlParameter("time", SqlDbType.DateTime2)
{
Direction = ParameterDirection.Output
};
using (var connection = new SqlConnection(ConnectionString))
{
connection.Open();
using (var command = new SqlConnection("SELECT #time = SYSDATETIME()", connection))
{
command.ExecuteNonQuery();
}
}
return (DateTime)parameter.Value;
}
Also you should never use DATETIME in SQL Server you should always use DATETIME2 as DATETIME is less accurate than C#::DateTime and it will lead to rounding errors. I know this from bitter experience.
If you are using Entity Framework, and your database is using datetime and not datetime2, the trick is to use SqlDateTime to match the fact that .Net goes to nanosecond, versus sql's millisecond precision. You can use your DateTime variable in .net.. for a SqlDateTime instance, and then you can uniquely identify a record down to the millisecond.
System.Data.SqlTypes.SqlDateTime entry2 = new System.Data.SqlTypes.SqlDateTime(new DateTime(dto.LookUpDateTime));
DateTime entry = entry2.Value;
var existticket = from db in context.Tickets
where db.LookupDateTime == entry && db.UserId == UserId
select db;
I am having a problem passing a C# DateTime value to a SQL Server 2005 stored procedure.
The stored procedure takes a parameter of type DateTime and updates a database column with the value passed (column also is datetime type):
ALTER PROCEDURE [dbo].[ProcedureName]
#id int,
#eta datetime
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
BEGIN TRANSACTION
UPDATE
TrackingTable
set
ETA = #eta
where
ID = #id
COMMIT TRANSACTION
END
I pass a C# datetime value to the stored procedure by creating a SqlParameter and executing a parameterised non query.
I can see via the analyser that the SQL executed is:
exec ProcedureName #id=19020, #eta='2012-07-17 10:29:34:000'
and if I execute this directly on the database the update works fine, but via my C# program it fails with the error:
The conversion of a char data type to a datetime data type resulted
in an out-of-range datetime value. The statement has been terminated.
I'm sure I'm being daft but I can't for the life of me see whats wrong. PS I'm new to SQL Server!
Any help appreciated!
Thanks.
Sorry the c# code:
dbWrapper.ExecuteProcWithParams("ProcedureName",
dbWrapper.CreateParameter("id", Header.VoyageID),
dbWrapper.CreateParameter("eta", ETA)
ETA is a DateTime Value.
public void ExecuteProcWithParams(string procName, params DbParameter[] parameters)
{
try
{
using (DbCommand cmd = db.CreateCommand())
{
cmd.Transaction = trans;
cmd.CommandText = procName;
cmd.CommandType = CommandType.StoredProcedure;
foreach (DbParameter param in parameters)
{
cmd.Parameters.Add(param);
}
cmd.ExecuteNonQuery();
}
}
catch (Exception)
{
throw;
}
}
public DbParameter CreateParameter(string name, object value)
{
DbParameter result = null;
switch (databaseType)
{
case DatabaseType.SqlServer:
// Sql Server: NULL parameters have to initialised with DBNull rather than NULL
result = new SqlParameter(name, value ?? DBNull.Value);
break;
default:
throw new Exception(String.Format("Unknown database type {0}", databaseType));
}
return result;
}
Try to set uiculture and culture in web.config.
<globalization uiCulture="en-GB" culture="en-GB"/>
Your passing date format and sql date can be different.
So set culture according to your culture.
I just faced a similar problem buddy!
It's because C# converts date time to MM-DD-YYY and SQL server generates date time based on DD-MM-YYYY.
That's why you get an out of bounds error on your month.
From my code, I call an SP using:
using (var cmd = new SqlCommand("sp_getnotes"))
{
cmd.Parameters.Add("#ndate", SqlDbType.SmallDateTime).Value
= Convert.ToDateTime(txtChosenDate.Text);
cmd.CommandType = commandType;
cmd.Connection = conn;
var dSet = new DataSet();
using (var adapter = new SqlDataAdapter { SelectCommand = cmd })
{
adapter.Fill(dSet, "ntable");
}
}
The Stored Procedure itself runs a simple query:
SELECT * FROM tblNotes WHERE DateAdded = #ndate
The problem is no records are returned! DateAdded is a smalldatetime column.
When I change the query to the following, it works:
SELECT * FROM tblNotes WHERE CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, DateAdded))) = #ndate
Why is this happening? This change affects the entire application and I'd like to find the root cause before getting into changing every single query... The only changes we made are to use parameterized queries and upgrade from SQL Server 2005 to 2008.
TIA.
smalldatetime has a time portion which needs to match as well.
Use this:
SELECT *
FROM tblNotes
WHERE dateAdded >= CAST(#ndate AS DATE)
AND dateAdded < DATEADD(day, 1, CAST(#ndate AS DATE))
SQL Server 2008 and above also let you use this:
SELECT *
FROM tblNotes
WHERE CAST(dateAdded AS DATE) = CAST(#ndate AS DATE)
efficiently, with the transformation to a range performed by the optimizer.
SQL Server 2008 now has a DATE data type, which doesn't keep the time porttion like SMALLDATETIME does. If you can't change the data type of the column, then you'll have to truncate when doing the compare, or simply cast to DATE:
SELECT *
FROM tblNotes
WHERE cast(dateAdded as date) = #ndate
I don't know SQL Server but from Oracle experience I'd suspect you're comparing a date time with a date, eg 01/01/2012 01:01:01 against 01/01/2012.
How to convert C# datetime to MySql Datetime format. I am getting value from text box like 7/27/2011 this format. But i want to convert in this format 2011-7-27. So here i am stuking. Please help me. My objective is to filter the record between two dates and show in a listview control in asp.net.
Here is my code:
DateTime dt1 = Convert.ToDateTime(txtToDate.Text);
DateTime dt2 = Convert.ToDateTime(txtFromDate.Text);
lvAlert.DataSource = facade.GetAlertsByDate(dt1, dt2);
lvAlert.DataBind();
I haven't used MySQL with .NET, but Oracle has similar date conversion issues with .NET. The only way to stay snae with this has been to use parameters for date values, both for input as welll as for WHERE clause comparisons. A parameter created with a MySQL date parameter type, and just giving it a .NET datetime value, should work without needing you to do conversions.
EDITED TO ADD SAMPLE CODE
This code sample shows the basic technique of using parameters for DateTime values, instead of coding conversions to text values and embedding those text values directly in the SQL command text.
public DataTable GetAlertsByDate(DateTime start, DateTime end)
{
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(
"SELECT * FROM Alerts WHERE EventTime BETWEEN #start AND #end", conn);
DataTable table = new DataTable();
try
{
SqlParameter param;
param = new SqlParameter("#start", SqlDbType.DateTime);
param.Value = start;
cmd.Parameters.Add(param);
param = new SqlParameter("#end", SqlDbType.DateTime);
param.Value = end;
cmd.Parameters.Add(param);
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(table);
}
finally
{
cmd.Dispose();
conn.Close();
conn.Dispose();
}
return table;
}
This is SQL Server code, but the technique should be the same for most databases. For Oracle, for example, the only changes would be to use Oracle data access objects, and use ":" in place of "#" in parameter names. The technique for MySQL should also be very similar.
For many databases, shortcuts may exist for creating parameters, such as:
cmd.Parameters.AddWithValue("#start", start);
This works when you know the value is not null, and the correct parameter type can be derived from the C# type of the value. "AddWithValue" is specific to SQL Server; "Add" works also but is obsolete in SQL Server.
Hope this helps.
You can assign format to data time, DateTime.ParseExact() or DateTime.ToString(format), :
the format for 2011-7-27 is yyyy-m-dd
Assuming you are doing this in the database I think you should use date_format to get in the required format
Something like date_format(dateval,'%Y-%c-%d') (Not tested)
I use:
string fieldate = dt1.ToString("yyyy-MM-dd");