Using SQL Server 2012, and the new date type (not dateTime) I created the next procedure:
CREATE PROC Test(#StartDate date ,#EndDate date)
AS
DECLARE #Temp TABLE([ID] int, [Date] date)
INSERT INTO #Temp SELECT 1, CONVERT(date,'31/12/2012',103)
INSERT INTO #Temp SELECT 2, CONVERT(date,'01/10/2012',103)
INSERT INTO #Temp SELECT 3, CONVERT(date,'01/01/2012',103)
SELECT * FROM #Temp WHERE [Date] BETWEEN #StartDate AND #EndDate
When I run this stored procedure I get the next error indicating the date format of the parameter:
Incorrect syntax near '/'.
Please what should be done ?
For one, your date shouldn't have a / in it. But it also needs to be enclosed in quotes. Try:
EXEC dbo.Test #StartDate = '20120101', #EndDate = '20120131';
The reason it needs to be enclosed in quotes is, if you don't use quotes, your "date" is interpreted as a mathematical expression, e.g.:
01/01/2012 = 1 divided by 1 divided by 2012
The reason your date shouldn't have a / in it is because m/d/y and d/m/y are unsafe formats that can be interpreted differently depending on language and other settings.
And finally, if you are calling this procedure from C#, why are you passing strings and not properly typed parameters?
Related
How can we pass the date (data type DateTime) in the execution command to run a stored procedure?
Here is the code snippet.
ALTER PROCEDURE [dbo].[datefiltered]
#months_margin int,
#oDate datetime
AS
BEGIN
SELECT *
FROM dbo.table20
WHERE date = oDate
-- more code...
END
I am trying to execute this stored procedure using GETDATE() function or even pass date and time as a string but it's not working.
exec datefiltered 23 getDate()
As you want to apply date filter, you don't need to pass datetime value. You can convert to DATE datatype for equality.
select * from dbo.table20
where date = CAST(#oDate AS DATE)
Also, if you are just passing GETDATE() as default, you can keep getdate as default value, as given below:
Alter procedure [dbo].[datefiltered]
#months_margin int,
#oDate datetime = null
AS
Begin
IF #oDate IS NULL
BEGIN
SET #oDate = CAST(GETDATE() AS DATE)
END
When you call the procedure with default value, you don't need to pass parameter value for it.
exec datefiltered 23 -- getdate() filter is applied automatically
ALTER PROCEDURE [dbo].[datefiltered]
#months_margin int,
#oDate datetime
AS
BEGIN
SELECT *
FROM dbo.table20
WHERE date = CAST(#oDate AS DATE)
-- more code...
END
Executing this stored procedure:
exec datefiltered 23, '2010-02-30'
I'm calling a SQL Server SP from Jupyter, and the SP looks like this:
ALTER
procedure [dbo].[proc_Report_QuarterlyDistribution02] (#quarter int, #year int, #group int)
as
declare #total int,
#date date
set #date = cast(#year as varchar(4)) + '-01-01'
set #date = dateadd(quarter, #quarter - 1, #date)
print #date
select #total = count(1)
from DimMedical
where ServiceDate between
DATEADD(quarter, -9,#date) and #date
and carriercode = #group
and Category = 'Physicians'
The SP goes on - that's not the issue.
The problem is the line
print #date
Question Why would the print statement cause the error:
ResourceClosedError: This result object does not return rows. It has been closed automatically.
Why would the print statement cause the error: "This result object does not return rows"
This is probably a limitation in the client library you are using. Some client libraries stop looking for a result set when they see a message.
Either remove the print statement, upgrade your client library (not mentioned), or have the stored procedure insert into a table using INSERT … EXEC, and then select from that in a subsequent query.
I'm getting the error
Invalid parameter 1 specified for dateadd.
when I try to execute the following dynamic parametrized query in SQL Server 2012:
DECLARE #Interval nvarchar(5) = 'DAY'
DECLARE #Increment int = 10
DECLARE #BaseDate date = getdate()
DECLARE #ResultDate date
DECLARE #Query nvarchar(2000)
SET #Query = 'SELECT #result = DATEADD(#Interval, #Increment, CAST(#BaseDate AS DATE))'
EXECUTE sp_executesql #Query,
N'#result date OUTPUT, #Interval varchar(50), #Increment int, #BaseDate date',
#Interval = #Interval, #Increment = #Increment,
#BaseDate = #BaseDate, #result = #ResultDate OUTPUT
SELECT #ResultDate
I've changed the SET #Query line to this one.
SET #Query = 'SELECT #result = DATEADD(' + #Interval +', #Increment, CAST(#BaseDate AS DATE))'
Although it works fine, I'm curious about why the first statement is causing the error in my dynamic SQL query?. Doesn't sp_executesql generate the same statement than the concatenated query one?
So the way to think about parameterized dynamic sql is you can only use a parameter where you could if it were static SQL. DATEADD expects a special date part keyword (e.g. day, hour, year, etc), not a literal string, and not a variable. It's the same issue some people run into where they think they can parameterize something like a table name. The first statement fails because even in static sql, this is invalid:
declare #increment nvarchar(5) = 'day'
select dateadd(#increment, 1, getdate())
That's equivalent to
select dateadd('day', 1, getdate())
The second statement succeeds because you're concatenating the string "day" which gets evaluated to the keyword.
In the first case, the query (with #Interval expanded to its value) becomes this:
SELECT #result=DATEADD('DAY', #Increment, CAST(#BaseDate AS DATE))
and in the second query it becomes this:
SELECT #result=DATEADD(DAY, #Increment, CAST(#BaseDate AS DATE))
The first query is invalid because there the first parameter to DATEADD is a string value, where the compiler expects a language keyword, and those are not the same in SQL.
For more info, see here: https://learn.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql
Please note the line under datepart saying User-defined variable equivalents are not valid. In other words you can't put quotes around these "values", they are not strings but keywords, and they can not be put in variables.
As it stands my colleague will be running the below query 30 times.
EXEC dbo.usp.Nameofstoredprocedure '01-nov-2016'
It exports 3 rows with columns ID, Name, type
Is there anyway to have it export as:
Date, ID, name, type
01-nov-2016,10,john smith,man
01-nov-2016,11,jane smith,woman
02-nov-2016,10,john smith, man
02-nov-2016,11,jane smith,woman
etc..
The stored procedure in question is not something I can copy and paste in due to policy.
Thinking it over, I can see a loop might work, possibly inserting the row into a table but I can't figure out how to do this, any assistance would be great.
Work so far:
declare #date date
set #date = '2016-11-01'
declare #inte int
while #inte >= 30
select * into #temp EXEC dbo.usp_GetMaxUsers #date
set #date = DATEADD(dd,1,#date)
set #inte = #inte + 1
Right now it's giving me the following error:
Msg 263, Level 16, State 1, Line 4
Must specify table to select from.
Msg 1038, Level 15, State 5, Line 4
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
Thanks.
You could try this:
CREATE TABLE <Table Name>
(
Date DateTime,
ID INT,
Name NVARCHAR(40),
Type NVARCHAR(6)
)
INSERT INTO <Table Name>
Exec <SP NAME> 'Params'
You need to run the create table only once of course then put the rest into an agent job to run whenever you need it to.
The real problem is the stored procedure should be redone to meet the requirements. Database objects often need refactoring too.
I would add an enddate optional parameter (with a default value of null, so it won't break existing uses of the proc). Then if only the first date was sent in, it would set the end date to the correct value to get only records from that date. Otherwise it would use both dates in the internal query(ies) to get the information over a date range.
The answer that worked.
declare #date2 date
set #date2 = '2016-11-01'
declare #inte int=0
while #inte <= 29
begin
create table #temp
(
ID int,
Name varchar(100),
Type varchar(50)
)
insert into #temp
exec [dbo].[usp_proceduregoeshere] #date2
insert into #Results
select #date2, *
from #Agents
drop table #temp
set #date2 = dateadd(day, 1, #date2)
set #inte = #inte+1
end
select *
from #Results
I am trying to create dynamic code for date calculation in SQL stored procedures but am having problems executing string expressions and parameters as date expressions.
I want to hold generic string expressions in a table that will create the dates according to the value of the parameters.
for example this is a generic expression :
DATEADD(#TimeResolution, -#IterationN, #CurrentCalc)
as you can see these generic expressions are composed out of parameters to.
in the stored procedures I intend to declare the variables that are in the expression and assign values to them using a select statement from a different table.
the problem is that after deriving these string values and writing the expression it does not give me the date I want but fails.
so for example if I write the following code
declare #Today date
declare #LastYear date
set #Today = getdate()
set #LastYear = DATEADD(year, -1, #Today)
select #Lastyear
it works fine and I will get last year's date.
but when I try something like this :
declare #Today date
declare #LastYear date
declare #Timeresolution varchar(5)
select #Timeresolution = [Timeresolution] from dbo.mytable where rule_id=1//Timeresolution is a varchar column in my table holding the values 'year' or 'month'
declare Iteration int
select #Iteration = [Iteration] from dbo.mytable where rule_id=1 //Iteration is a int column in my table holding the values 1 or 2, or 3
set #Today = getdate()
set #LastYear = DATEADD(Timeresolution , -Iteration , #Today)
select #Lastyear
this gives me a conversion error.
Is there a way to create such dynamic date expressions?
It isn't possible to use a variable for the interval in DATEADD, but you can do something like this:
IF #Timeresolution = 'year'
BEGIN
SET #LastYear = DATEADD(year, -#Iteration , #Today)
END
IF #Timeresolution = 'month'
BEGIN
SET #LastYear = DATEADD(month, -#Iteration , #Today)
END