use of IsNull with date - tsql

I have the following TSQL code:
Declare #MyDate datetime
Select #MyDate = ISNULL(T.requireddate, Convert(DateTime, '01/01/2013', 101))
from myTable T
where T.somekey = somevalue
Select #MyDate
The output is NULL. Why isn't it 01/01/2013?

Are you sure that select returns any rows?
If that select returns no rows then #MyDate would be null
Try
Select T.requireddate, ISNULL(T.requireddate, Convert(DateTime, '01/01/2013', 101))
from myTable T
where T.somekey = somevalue

Related

Adding Parameter causing issues-No data displayed

Hi all I have a stored procedure with two parameters #Startdate and #Enddate. When i execute the procedure i get data.
Now i added a parameter and it has list of values. So i added a split function and added in the WHERE clause. Now after making the changes when i execute my SP i do not get any data. I tried commenting out the 3rd Parameter from the WHERE clause and now i see the data again. Not sure what is happening. Any advice is greatly appreciated.
I have tried different split functions and Charindex(','+cast(tableid as varchar(8000))+',', #Ids) > 0 and nothing has worked.
Thanks
NOTE: The concatenation and splitting of parameter values is a poor design for performance reasons and, most importantly, very susceptible to SQL injection attacks. Please research some alternatives. If you must proceed down this path...
There are a great many split functions out there, but I used this one here to illustrate a possible solution.
CREATE FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output (splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
END
GO
It's unclear, from your question, if you need to filter your results based on an int, varchar or various other data types available, but here are two options (and probably the most common).
DECLARE #TableOfData TABLE
(
ID_INT INT,
ID_VAR VARCHAR(100),
START_DATE DATETIME,
END_DATE DATETIME
)
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #Ids VARCHAR(1000)
DECLARE #Delimiter VARCHAR(1)
SET #Delimiter = ','
SET #StartDate = GETDATE()
SET #EndDate = DATEADD(HH, 1, GETDATE())
SET #Ids = '1,2,4'
--Create some test data
INSERT INTO #TableOfData
SELECT 1, '1', GETDATE(), DATEADD(MI, 1, GETDATE()) --In our window of expected results (date + id)
UNION SELECT 2, '2', GETDATE(), DATEADD(D, 1, GETDATE()) --NOT in our window of expected results b/c of date
UNION SELECT 3, '3', GETDATE(), DATEADD(MI,2, GETDATE()) --NOT in our expected results (id)
UNION SELECT 4, '4', GETDATE(), DATEADD(MI,4, GETDATE()) --In our window of expected results (date + id)
--If querying by string, expect 2 results
SELECT TD.*
FROM #TableOfData TD
INNER JOIN dbo.fnSplitString(#Ids, #Delimiter) SS
ON TD.ID_VAR = SS.splitdata
WHERE START_DATE >= #StartDate
AND END_DATE <= #EndDate
--If querying by int, expect 2 results
SELECT TD.*
FROM #TableOfData TD
INNER JOIN dbo.fnSplitString(#Ids, #Delimiter) SS
ON TD.ID_INT = CONVERT(int, SS.splitdata)
WHERE START_DATE >= #StartDate
AND END_DATE <= #EndDate
You cannot use a parameter with a list directly in your query filter. Try storing that separated data into a table variable or temp table and call that in your query or use dynamic SQL to write your query if you don't want to use table variable or temp tables.

Optionnal parameter in SEARCH CFQL method not of type varchar

Is it possible to have a search function that would allow passing optional parameters other than varchar (i.e. DateTime, decimal .. ) ?
I need to search rows that are in a date range. User should be able to search FROM a date only, or up TO a date, or even in a FROM-TO range.
My approach was to create a SEARCH method with Date parameters. Those are correctly converted to DateTime object in CFE, but I won't be able to pass null value.
I managed to create a SEARCH method with unchecked parts, but those parts won't get optionnal in the body of the function.
How can I get fromDate and toDate parameters to be set as optional ?
CFQL body is
SEARCH(string amount, string fromDate, string toDate, string otherEntityId, date date) WHERE [$Entity::Date$ >= CAST(#fromDate AS DATE)] AND [$Entity::Date$ <= CAST(#toDate AS DATE)] AND OtherEntity.OtherEntityId = #otherEntityId AND Amount = #amount and date = #date
Body procedure generated is as follow. Notice the unchecked parts that aren't optionals
CREATE PROCEDURE [Schema].[Entity_NameOfProcedure]
(
#amount [nvarchar] (256) = NULL,
#fromDate [nvarchar] (256) = NULL,
#toDate [nvarchar] (256) = NULL,
#OtherEntityId [nvarchar] (256) = NULL,
#date [date] = NULL,
#_orderBy0 [nvarchar] (64) = NULL,
#_orderByDirection0 [bit] = 0
)
AS
SET NOCOUNT ON
DECLARE #sql nvarchar(max), #paramlist nvarchar(max)
SELECT #sql=
'SELECT DISTINCT * /*on purpose for stackoverflow */
FROM [Schema].[Entity]
LEFT OUTER JOIN [Schema].[OtherEntity] ON ([Schema].[Entity].[Entity_OtherEntity_OtherEntityId] = [Schema].[OtherEntity].[OtherEntity_OtherEntityId])
WHERE (([Entity].[Entity_Date] >= CAST(#fromDate AS DATE) AND ([Entity].[Entity_Date] <= CAST(#toDate AS DATE) AND ((1 = 1) AND ((1 = 1) AND (([Schema].[OtherEntity].[OtherEntity_NumberInt] LIKE ''6%'') AND (1 = 1)))))) AND (1 = 1))'
SELECT #paramlist = '#amount nvarchar (256),
#fromDate nvarchar (256),
#toDate nvarchar (256),
#otherEntityId nvarchar (256),
#date date,
#_orderBy0 nvarchar (64),
#_orderByDirection0 bit'
IF #amount IS NOT NULL
SELECT #sql = #sql + ' AND (([Schema].[Entity].[Entity_amount] = #amount))'
IF #otherEntityId IS NOT NULL
SELECT #sql = #sql + ' AND (([Schema].[OtherEntity].[OtherEntity_OtherEntityId] = #OtherEntityId))'
IF #date IS NOT NULL
SELECT #sql = #sql + ' AND (([Schema].[Entity].[Entity_Date] = #date))'
EXEC sp_executesql #sql, #paramlist,
#amount,
#fromDate,
#toDate,
#OtherEntityId,
#date,
#_orderBy0,
#_orderByDirection0
RETURN
GO
Thanks for your answer
You can create a SEARCH method with optional date parameters:
SEARCH(date fromDate, date toDate)
WHERE CreationDate >= #fromDate AND CreationDate <= #toDate
This generate the following SQL:
SELECT #sql=
'SELECT DISTINCT [Employee_Id], [Employee_FirstName], [Employee_CreationDate]
FROM [Employee]
WHERE (1 = 1)'
SELECT #paramlist = '#fromDate datetime, #toDate datetime'
IF #fromDate IS NOT NULL
SELECT #sql = #sql + ' AND (([Employee_CreationDate] >= #fromDate))'
IF #toDate IS NOT NULL
SELECT #sql = #sql + ' AND (([Employee_CreationDate] <= #toDate))'
The fromDate and toDate parameters are not nullable in the generated BOM. However if you use the default value which by default is equal to CodeFluentPersistence.DefaultDateTimeValue (More about default values), NULL will be sent to the store procedure.
If you prefer DateTime? just change the type of the parameter from date to date?
SEARCH(date? fromDate, date? toDate)
WHERE CreationDate >= #fromDate AND CreationDate <= #toDate
Which generate the following C# method:
public static EmployeeCollection Search(DateTime? fromDate, DateTime? toDate)

how convert string variable to datetime variable in sql-server?

I'm relatively new to sql-server; I'm trying to have a start-date and end-date pulled from a form-variable as string then convert it into datetime (yyyy-mm-dd) format and I can't seem to find anything that works. Attempted code and resulting error is below. Any advice would be appreciated.
declare #startdate as varchar
declare #enddate as varchar
set #startdate=cast(#startdate as datetime)
set #enddate=cast(#enddate as datetime)
SELECT order_date, inv_no
from invoices
where order_date between #startdate and #enddate
The error I keep getting is:
Conversion failed when converting datetime from character string.
How do I fix this?
specify a length for your varchar:
declare #startdate as varchar(10)
declare #enddate as varchar(10)
set #startdate=cast(#startdate as datetime)
set #enddate=cast(#enddate as datetime)
SELECT order_date, inv_no
from invoices
where order_date between #startdate and #enddate
you don't have to cast necessarily
declare #startdate varchar(50)
declare #enddate varchar(50)
declare #start datetime = #startdate, #end datetime = #enddate
select #start, #end

How do you initialize a variable in a stored procedure with a function

How do you initialize a variable in a stored procedure with a function?
This doesn't work:
/****** Object: StoredProcedure [dbo].[usp_ShowBackpopGaps] Script Date: 05/25/2011 19:57:23 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[usp_ShowBackpopGaps]
-- Add the parameters for the stored procedure here
#StartDate datetime = DateAdd(yy, -1,getdate()),
#EndDate datetime = getdate
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
;with dateranges as(
select DateAdd(dd,-1,EtlStartDate) as DateFrom,
DateAdd(dd,1,EtlEndDate) as DateTo
from EtlJobRunStatus
where JobRunStepID like 'ETL[0-9]%' and EndTime is not null
union all
select #StartDate ,#StartDate
union all
select DateAdd(dd,-1,#EndDate),DateAdd(dd,-1,#EndDate)
)
select DateAdd(dd,-1,DateTo) as MissingFrom,
DateAdd(dd,1,NextDateFrom) as MissingTo,
DateDiff(d,DateTo, NextDateFrom) as MissingDays
from (
select distinct DateFrom, DateTo as DateTo,
(select MIN (dateFrom)
from dateranges
where DateTo > D.DateTo
) as NextDateFrom
from dateranges D
) X
where DateTo < NextDateFrom
END
GO
You can't have a function call as a parameter default.
I think you need
CREATE PROCEDURE [dbo].[usp_ShowBackpopGaps]
#StartDate DATETIME = NULL,
#EndDate DATETIME = NULL
AS
BEGIN
SET #StartDate = ISNULL(#StartDate,DATEADD(yy, -1,GETDATE()))
SET #EndDate = ISNULL(#EndDate, GETDATE())
...

parser datetime via tsql

Update List
set Date = "2009-07-21T19:00:40"
sql server doesn't recognize this format. is there a conversion function
You can use CAST and CONVERT. But maybe you must replace the 'T' with a space, before you can convert it. (There are also string manipulation functions available.)
Worked just fine for me (SQL Express 2005) except for the double quotes (which SQL Server assumed was a column delimiter); is that what's throwing the error? Thanks for the sample code, but can you produce the actual error?
In other words,
DECLARE #List TABLE ( [date] DATETIME
)
INSERT INTO #List
SELECT GETUTCDATE()
UPDATE #List SET Date =
"2009-07-21T19:00:40"
produces
Msg 207, Level 16, State 1, Line 7
Invalid column name
'2009-07-21T19:00:40'.
Whereas
DECLARE #List TABLE ( [date] DATETIME
)
INSERT INTO #List
SELECT GETUTCDATE()
UPDATE #List SET Date =
'2009-07-21T19:00:40'
runs successfully.
Try this:
UPDATE List SET Date = '2009/07/21 19:00:40'
Even worked for me too(2005 & 2008)..
DECLARE #tbl TABLE ( [date] DATETIME )
INSERT INTO #tbl SELECT getdate()
select * from #tbl
UPDATE #tbl SET Date = '2009-07-21T19:00:40'
select * from #tbl
However, just give a shot with DATEFORMAT COMMAND
Something like this
**SET DATEFORMAT dmy**
DECLARE #tbl TABLE ( [date] DATETIME )
INSERT INTO #tbl SELECT getdate()
select * from #tbl
UPDATE #tbl SET Date = '2009-07-21T19:00:40'
select * from #tbl