I'm having a problem with some T-SQL in a SP on SQLServer 2005 comparing dates. I'm running the stored procedure from c# with ADO.Net and passing a the native c# datetime datatype(could this be my issues as I know the ranges are slightly different). I do the following to compare 2 DateTime values in my SP.
CREATE PROCEDURE [dbo].[spGetLikelyMatchedIndividuals_v1]
#ID BIGINT = NULL,
#DOB DATETIME = NULL, ...
WHERE ISNULL(CONVERT(CHAR(8),Ind.[DateOfBirth],112),'') = ISNULL(CONVERT(CHAR(8),#DOB,112),'')
This works fine in most cases but from some reason will fail with some Datetime. This is one datetime value that fails:
1925-07-04
Does anyone have anyidea why this may fail? Also what is the best way to compare two date values without the time component?
Seems like your date compare is correct. It may be other logic that is causing this issue. Perhaps you should paste in more of your stored procedure to find the likely problem.
Better yet, don't do any logic against the table as this will prevent your index from being used.
Let your front end app handle the ensuring that the #DOB variable is in the correct format.
If you're comparing dates on SQL-Server, investigate the DateDiff function.
You can compare two dates quite easily and specify the granularity, eg. to the nearest day or hour or minute or whatever.
In your example, one of your values is a datetime, so convert the other to that type using the Convert function.
You just want to compare the date component? You could compare
FLOOR(CAST(x.[SomeDate] as float)) = FLOOR(CAST(#SomeDate as float))
A lot less string work, and should do the job. Even better; create a 1-day range and use that...
DECLARE #from datetime, #to datetime
SET #from = CAST(FLOOR(CAST(#SomeDate as float)) as datetime)
SET #to = DATEADD(day, 1, #from)
...
WHERE x.[SomeDate] >= #from AND x.[SomeDate] < #to
String operation is expensive at times. Here is an example of selecting dates ignoring the time part without any casting:
Select dateadd(dd,0, datediff(dd,0, yourdatetimeval)) as date_column
Related
I have month in an integer variable int month =DateTime.Now.Month; and I have Two dates in database they are '11/01/2014'and '11/30/2014' . Now I want to bring least and grater days in a string. how can I achieve it.(in database I have Fromdate('11/01/2014') and Todate('11/30/2014')fields)? I am new in this field.
There are Min and Max functions you can use to find this. The best way to use these is to ensure that you are first storing the date as a date or datetime value (or similar), as casting from one type to another can be an expensive operation.
Sample:
Select Min( MyDateColumn) as "MinDate", Max(MyDateColumn) as "MaxDate"
From MyTable;
If they are not stored as a form of date value, you will have to cast the value to a date. If it is stored as a varchar or char, for example, you will need to do this. If you don't, the min and max will be calculated based on the ascii values of characters, not on the actual dates.
Sample (avoid, if possible):
Select Min( CAST(MyDateColumn as date) ) as "MinDate",
Max( CAST(MyDateColumn as date) ) as "MaxDate"
From MyTable;
I have to write a query to get rows where date is like current date.
I don't want to compare the the time part but only date part.
Like today's date is 2014-05-03
but in table its in datetime as 2014-05-03 10:08:22
i tried [http://www.w3schools.com/sql/func_convert.asp]
but could not do anything..
my query is like
select *from dbo.param where cvdatetime like '2014-05-03%';
but its does not work although if i use
select *from dbo.param where cvdatetime like '%2014%';
it works so i don't get why "like" can't work in the previous case
i just want to compare the date part only not the time part..
like in c# i will take the current date as
string today_n = DateTime.Now.ToShortDateString();
which will give only today's date
the query will be like
string query="select *from dbo.param where cvdatetime like '" + today_n + "%'"
what is the correct way?
also i want that whatever be the system date format query should work like even if system date time format is dd-mm-yyyy hh:mm:ss tt the query should work how can i ensure this?
Adding new requirement what if I need to check date hh:mm: only not seconds
i.e, 2014-05-04 12:00: part only not seconds part
You cannot use like as such on datetime column.
Use the below:
select * from dbo.param where convert(varchar, cvdatetime, 120) like '%2014%';
As, far your second question is concerned, you'll have to use parameterized queries to avoid sql injection attacks.
Using SQL Server 2005 or later, just convert the datetime to date:
select *
from dbo.param
where cast(cvdatetime as date) = '2014-05-03';
Do not think about dates as strings. Think of them as dates, with the string format only used for output purposes. Or, if you have to make an analogy to another type, think numbers. As an example, go into Excel, put a date into a cell. Nicely format it. Then set another cell equal to the value of the first cell (=A1 for example). Format that as a number and you will see some strange number, probably in the range of about 40,000. Excel stores dates as number of days since 1970-01-01. SQL has a similar (but different) storage mechanism.
You can use the following for the current date:
SELECT *
FROM dbo.param
WHERE CONVERT(DATE, cvdatetime) = CONVERT(DATE, GETDATE())
I have an SQL stored procedure which accepts a DateTime parameter which has a default value of NULL
#pmNext_Check_Date DATETIME=NULL
I want to use this parameter in 3 scenarios:
If it's NULL then don't update any records
If it's got a date value then update all my records specified in my WHERE clause
The problem one! Set all the date fields in my query to NULL for the records in my WHERE clause.
Here is the block of code within the SP that is causing me issues (the rest of the UPDATE statement is build elsewhere in the SP and works fine):
IF #pmNext_Check_Date IS NOT NULL
IF #pmNext_Check_Date ='' --This is the bit that is causing me a problem. I just need to check for a empty date
SET #sql = #sql + ' Next_Check_Date = NULL '
ELSE
SET #sql = #sql + ' Next_Check_Date = #pmNext_Check_Date '
SET #sql = #sql + ' WHERE ID IN (1, 2)'
So for example if I have the following 2 rows:
ID NextCheckDate
1 12/12/12
2 NULL
In scenario 1 I wouldn't pass the parameter in as the procedure will use the default value and no dates will be updated.
In scenario 2 I pass in a date value and update both rows with the date value
In scenario 3 I want to update the date value on my rows to be null. The difference between scenario 1 & 3 is in scenario 3 the user will be choosing to set the date values to null.
So, I wanted to pass a blank date into the stored procedure. I'm doing this from C# and would like to do something like the following:
SqlParameter param = new SqlParameter("#pmNext_Check_Date", "");
This fails as the SP is expecting a DateTime.
So I want to be able to pass in a blank date and also how do I check this within the SP. The current check which is below doesn't work:
IF #pmNext_Check_Date =''
Thanks in advance.
Hope this all makes sense.
I'm using C#4.0 and SQL 2008
There is no such thing as a "blank date". You could use a well-known sentinel value (01 Jan for some arbitrary ancient year, for example), but null would be preferable. Note that to pass an explicit null via a parameter, you need:
SqlParameter param = new SqlParameter("#pmNext_Check_Date", DBNull.Value);
If that doesn't have enough granularity, consider adding a separate boolean (bit) parameter (or similar) that clarifies what you want the sproc to do. Or: have multiple procs to do these different things.
One useful sentinel value for SQL Server is January 1, 1753 (SQL Server's minimum datetime value) - this can be produced in TSQL without string parsing as cast(-53690 as datetime).
You can't pass an empty string as a datetime. So, you have a couple options. You could add an additional parameter to indicate whether or not an update should occur. I suggest that as the best options for code readability and maintainability. The other option would be to pass in the parameter as a string and parse it. That way you could use your empty string concept.
Sql Server string to date conversion
Sorry, there is no way to do precisely what you're asking. A DATETIME value is either NULL or a valid date, there is no "empty" like there is with strings.
Another workaround is to pass a token value (that wouldn't be a valid date otherwise) to represent your so-called empty string, e.g. a common one I've seen used is 1900-01-01. Then you can differentiate in your stored procedure between NULL and "empty."
But I don't recommend doing this at all. I agree with the other suggestions: add another parameter and do the logic in a more meaningful way in the stored procedure.
If I can recall correctly, columns with a DATETIME datatype which allow NULLS
will default to the value 1900-01-01 instead of a BLANK value.
For example:
NULLS may be allowed for certain columns which might receive a value later down the line based on some kind of business logic. I have seen folks keep these open ended columns as varchar to enable a custom entry of some type or an empty string, something which datetime will not allow.
If you ask me I'd try not to mess around with the base column's data type and let it remain as DATETIME. For data retrieval and reporting purposes we might try the following approach, which may not be the best way to do it. But it works.
BEGIN
DECLARE #VarcharDateTable TABLE
([EndDate_Varchar] varchar(27))
BEGIN
INSERT INTO #VarcharDateTable([EndDate_Varchar])
SELECT
CONVERT(varchar(27), [EndDate_Datetime], 121)
FROM [dbo].[MainTable]
END
BEGIN
SELECT CASE WHEN [EndDate_Varchar] LIKE '1900-01-01%'
THEN 'Data unavailable'--or whatever you want
ELSE [EndDate_Varchar]
END AS [EndDate_Varchar] FROM #VarcharDateTable
END
END
I have a variable which is datetime type. How can i get the shortdatetostring() as datetime variable type ? I have a column in databae as datetime type. I would like to get the records which are added at a certain day.
Example:
SELECT id FROM database WHERE added like #p1
The parameter of the query is a datetime variable.
Match based on day, month, and year of the date variables. Do not use strings, since matching is slow.
SELECT id
FROM database
WHERE Datepart(yy, added) = Datepart(yy, #p1)
AND Datepart(mm, added) = Datepart(mm, #p1)
AND Datepart(dd, added) = Datepart(dd, #p1)
You could do something like this in order to get all the ids on the 26th of January.
SELECT id FROM database WHERE added >= '2012-01-26' and added < '2012-01-27'
In C# you do like below.
DateTime dt;
string Temp1 = "Your Date";
if (DateTime.TryParse(Temp1, out dt))
{
// If it is a valid date
string date = dt.ToShortDateString();
string time = dt.ToShortTimeString();
}
In SQL Server
SELECT id FROM database WHERE Datepart(dd, added) = Datepart(dd, #p1)
Please see below the sample
create table #temp
(
dat datetime,
)
insert into #temp(dat)values(GETDATE())
insert into #temp(dat)values(GETDATE()+1)
insert into #temp(dat)values(GETDATE()+2)
select * from #temp where DATEPART(dd, dat) > 27
drop table #temp
If you are using parameterised queries the format of the datetime type doesn't matter.
Got to remember that "2012-01-26" is a string not a date....
If you need a Date formatted a particular way, then myDateTime.ToString(....), there are several overloads, one of which is simply a format String e.g. "yyyy-MM-dd"
If you want to parse a string into a datetime then DateTime.Parse(...), again there are several overloads.
More on dates after comment
DateTime.Parse("12/31/2012") gives you a datetime type in c#.
It parses the string into a DateTime
MyDateTime.ToString("MM/dd/yyyy") gives you a string of date in the specified format.
"31/12/2012" is not a date, if you want it as a date, then you Parse it into one.
Now which way do you want to go DateTime to a string, or string to a DateTime, or are you asking something completely different?
If you want to only Parse DateTimes trhat are in the format mm/dd/yyyy, you can't because when it's string there's absolutely no way to tell the 6th of August from the 8th of June, unless you assume the format is always mm/dd/yyyy which is pretty much guaranteed to go badly wrong at somepoint, which is why when going from Date to String YYYYMMDD or YYYY-MM-DD are the way to go.
If it's what you want / have to do then
DateTime MyDateTime = DateTime.Parse("12/31/2012",CultureInfo.CurrentCulture);
Pass a string in a format that doesn't fit the pattern and it will throw an exception, NB that would include "31/12/2012".
CultureInfo is in the System.Globalisation namespace.
There area number of options. Current, CurrentUI, Invariant etc. Which one you use depends on how you are setup and globalisation / internationalisation requirements (even if they are none). So using Current Culture, would assume US default regional settings. But if I was to run your code, then "31/12/2012" would work and "12/31/2012" would blow chunks.
If you want to fix the formats no matter what system they are run on then InvariantCulture is the way to go. Don't forget to set the neutral language as well. Hit the assembly button on the Applications tab of the project's property pages. Neutral language is a drop down near the bottom. Presumably you want en-us.
If you don't want the excpetion then it's
DateTime myDateTime;
if (DateTime.TryParse("12/31/2012",CultureInfo.CurrentCulture, out myDateTime)
{
// do something with myDateTime...
}
else
{
// do something about the value not being in the correct format
}
You might be able to simplify this by editing the query, actually. Try
select id from database where cast(added as date) = cast(#p1 as date)
This (effectively) strips the time from added as well as the time from #p1 and compares the dates only.
I have a Db server with DateTime fields in the format of "yyyy-MM-dd mm:hh:ss"
I'm trying to use linq2sql to insert a DateTime member to a DateTime field in one of my tables.
When I do it in SQL I convert the DateTime as following:
"Insert into .... Convert(datetime, getdate(), 120) ..."
But when I try to submit the object from Linq the date time inserts in the wrong format.
Is there a way to define the format that will be inserted to the Db in Linq?
Or is it a DateTime object Issue?
You shouldn't be dealing with a string format when you pass dates and times to the database, any more than you would if you were passing a number. The database should be handling all this for you without any conversions. This is true whether you're using LINQ or within the SQL - almost any time you have to manually do string conversions between types at the database level, you should look for a better solution.
If you read the value back out of the database (as a DateTime again) does it have the right value? If not, in what way is it wrong?