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

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())
...

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.

use of IsNull with date

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

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

Optional parameters and date index

I'm playing around with two very simple queries. There is a non-clustered index with StartDate and EndDate, as well as Id as an included column.
DECLARE #startDate DATETIME, #endDate DATETIME
SELECT #startDate = '4/1/2011', #endDate = '5/1/2011'
-- Does Index Scan (slow)
SELECT Id
FROM dbo.Table
WHERE
(#startDate IS NULL OR StartDate >= #startDate) AND
(#endDate IS NULL OR EndDate < #endDate)
-- Does Index Seek (fast)
SELECT Id
FROM dbo.Table
WHERE
(StartDate >= #startDate) AND
(EndDate < #endDate)
Is there any way to rearrange, pre-calculate, or otherwise change the query to have an index seek occur in the first example?
Edit: I know this is a very basic indexing problem, but I haven't found a good solution yet. Note that I am declaring the variables, but those would be parameters in an sproc.
What about the following?
DECLARE #startDate DATETIME, #endDate DATETIME
SELECT #startDate = '4/1/2011', #endDate = '5/1/2011'
SELECT Id
FROM dbo.Table
WHERE
StartDate >= ISNULL(#startDate, '1/1/1753')
AND
EndDate < ISNULL(#endDate, '12/31/9999')
This code is probably broken if you have an end date of 12/31/9999 in your table that you actually want returned from your result set, but how often does that happen?

execute programmatically stored procedures with different parameter values

I have stored procedure
getList(#date datetime)
how programmatically execute stored procedure for differend datetime values.
datetime each month for 3 years.
You can try something like this
DECLARE #StartDate DATETIME,
#EndDate DATETIME
SELECT #StartDate = '01 Jan 2005',
#EndDate = '31 Dec 2007'
WHILE #StartDate <= #EndDate
BEGIN
PRINT #StartDate
EXEC getList(#StartDate)
SET #StartDate = DATEADD(mm, 1, #StartDate)
END
Just add one month to the current date?
DATEADD(month, 1, GETDATE())