I'm first time trying to write a stored procedure in sql server and the codes as below. Here when I add "with rollup" at the end of the query, it shows error "Incorrect syntax near the keyword with"
DROP PROCEDURE FIRSTPROCEDURE
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE FIRSTPROCEDURE
#startdate nchar(8), #enddate nchar(8)
AS
BEGIN
SET NOCOUNT ON;
select Date, SUM(QT1), SUM(QTY2), SUM(qTY3) FROM dbo.TABLE1
where date between #startdate and #enddate
group by Date
order by Date
WITH ROLLUP
END
GO
And tried to execute the procedure as below :
exec firstprocedure '20120501', '20120525'
With rollup needs to come before the order by. It's related to the group by
select Date, SUM(QT1), SUM(QTY2), SUM(qTY3) FROM dbo.TABLE1
where date between #startdate and #enddate
group by Date WITH ROLLUP
order by Date
Also, you'll avoid a whole bunch of issues if you store and query your dates using the date datatype
Related
I'm trying to recreate PostgreSQL generate_series function in SQL Server for DATE type like below
CREATE OR ALTER FUNCTION dbo.generateDatesBetween(#startdate DATE, #enddate DATE)
RETURNS TABLE (date DATE)
AS BEGIN
DECLARE #res TABLE(date DATE);
WHILE #startdate <= #enddate
BEGIN
INSERT #res(date) VALUES(#startdate)
SET #startdate = DATEADD(DAY,1,#startdate)
END;
RETURN #res
END;
But it keeps showing this error
[S0001][156] Incorrect syntax near the keyword 'BEGIN'
I've tried to create many functions before this, but it works just fine with BEGIN keyword.
Anyone know how to solve this? Thanks
You can modify the function like below to make it work. You cannot have the table variable with RETURN keyword in Table valued user defined function. You can do that only in the scalar user defined function.
CREATE FUNCTION dbo.generateDatesBetween(#startdate DATE, #enddate DATE)
RETURNS #res TABLE(date DATE)
AS BEGIN
WHILE #startdate <= #enddate
BEGIN
INSERT #res(date) VALUES(#startdate)
SET #startdate = DATEADD(DAY,1,#startdate)
END;
RETURN;
END;
I want to pass the system date (GETDATE) only as a parameter in my SQL stored procedure. But I am getting an error while executing the procedure.
SQL query:
ALTER PROCEDURE ST_PRO_GETUSER
#D DATETIME = GETDATE --// passing GETDATE as a parameter.
AS BEGIN
select case when branch in ('A25','B10','C10')
then 'BR B1' Else 'BR B2'
end As [COLLECTION],FIXDATE
from MAIN_COUNTER where TDATE=#D --//Just want to pass date only
group by COLLECTION,FIXDATE
END
EXEC KK_SP_GETUSER_DIV
Error:
Conversion failed when converting date and/or time from character string.
What I have to do for it?
To pass as a parameter you just declare a variable and pass it in:
DECLARE #DATE DATETIME = GETDATE();
EXEC ST_PRO_GETUSER #DATE;
And if you want the date only, change the datatype of your parameter to a date and then do:
DECLARE #DATE DATE = GETDATE();
EXEC ST_PRO_GETUSER #DATE;
But part of your question seems to actually be asking how to specify a default parameter value. You can't use a function for the default value, so instead do:
CREATE PROCEDURE ST_PRO_GETUSER
(
#Date DATETIME = null
-- Change to DATE datatype if you don't want a time component.
-- #Date DATE = null
)
AS
BEGIN
SET NOCOUNT ON;
-- Default the #Date here is its null.
-- Note this doesn't handle the case when the caller wants to pass in null.
SET #Date = COALESCE(#Date,GETDATE());
-- SP Body
RETURN 0;
END
Solved My Self
ALTER PROCEDURE ST_PRO_GETUSER
#Date datetime = null
as
IF #Date is null
SET #Date = getdate() --// passing GETDATE as a parameter.
BEGIN
select case when branch in ('A25','B10','C10')
then 'BR B1' Else 'BR B2'
end As [COLLECTION],FIXDATE
from MAIN_COUNTER where TDATE=#D --//Just want to pass date only
group by COLLECTION,FIXDATE
END
EXEC ST_PRO_GETUSER
GETDATE() is the correct syntax, not GETDATE.
I have tried to make a procedure to insert a price:
create procedure prInsertPrice
#NuggetID varchar(5),
#Unit_Price money,
#Start_Date datetime,
#End_Date datetime
as
begin
DECLARE #date AS DATETIME
SET #date = GETDATE()
if
(
(#NuggetID like 'N[0-9][0-9]')
and
(#Unit_Price is not null)
and
(#Start_Date is not null)
)
begin
print 'Insert Success'
insert NuggetPrice (NuggetId, Unit_Price, Start_Date, End_Date)
values (#NuggetID, #Unit_Price, #Start_Date, #End_Date)
end
else
begin
print 'Failed to insert'
end
end
When I execute the procedure it's fine, but when I run the procedure like this:
EXEC prInsertPrice 'N01', 20000, #date, null
I get the error message:
Must declare the scalar variable #date.
Why is this and how can I correct the problem?
The #date in the exec statement is different then the one in the stored proc.
You should do something like:
DECLARE #date AS DATETIME
SET #date = GETDATE()
EXEC prInsertPrice 'N01', 20000, #date, null
When you run:
EXEC prInsertPrice 'N01', 20000, #date, null
You are passing the variable #date as the third parameter to your stored procedure, as #Start_Date. This is entirely separate from the #date variable which you have declared inside the stored procedure itself, which gets declared and initialised after the procedure has been called, as it executes.
If you have not initialised the #date variable which is being passed as a parameter to the stored procedure before calling the stored procedure, then you will get the error you have described.
So, you need to declare and initialise this variable first:
DECLARE #date DATETIME = '2017-01-01' -- You can whatever date value you require here
EXEC prInsertPrice 'N01', 20000, #date, null
This should prevent the error.
Note: You can also separate the declaration and initialisation of the #date variable if you would prefer:
DECLARE #date DATETIME
SET #date = '2017-01-01'
In addressing your underlying problem though or preventing bad data being inserted into your NuggetPrice table though, I would agree with Prdp's suggestion of adding a CHECK Constraint to the table, for example:
ALTER TABLE NuggetPrice
ADD CONSTRAINT CK_NuggetPrice CHECK (NuggetID LIKE 'N[0-9][0-9]'
AND Unit_Price IS NOT NULL
AND Start_Date IS NOT NULL)
This would also prevent anyone from inserting records which do not agree with the logic specified.
Already other two answers gave enough information on the reason for error so am not going to talk about it. Here is different approach to solve the data validation
Instead of creating a Stored Procedure to restrict inserting bad data into table, I would suggest you to create a Check constraint to do this
ALTER TABLE NuggetPrice
ADD CONSTRAINT CK_NuggetPrice CHECK (NuggetID LIKE 'N[0-9][0-9]' AND Unit_Price IS NOT NULL AND Start_Date IS NOT NULL)
This will make sure nobody inserts bad data in NuggetPrice
I have the following stored procedure, it works fine except that when returns all the results it will start over and create another window, it is looping over and over creating table after table with the same results. What could be causing this?
USE [HRLearnDev]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[COL_Run_DOM_Parameters]
#StartDate varchar (50),
#EndDate varchar (50)
AS
SET NOCOUNT ON
SELECT *
FROM dbo.COL_V_GEMS_DOM_FCT
WHERE REC_EFF_STT_DT BETWEEN #StartDate and #EndDate
ORDER BY REC_EFF_STT_DT DESC
EXECUTE COL_Run_DOM_Parameters #StartDate = "2010-03-05", #EndDate = "2011-06-11"
I don't think you want to do this within your stored procedure (ie: REMOVE it):
EXECUTE COL_Run_DOM_Parameters #StartDate = "2010-03-05", #EndDate = "2011-06-11"
This indicates the procedure is calling itself recursively, over and over and over ...
(Unless this was mistakenly included, and was just shown as an example of how you WOULD call the stored proc)
I have one big SQL query and I want to pull out some data using that query
declare #Period VARCHAR(10) = 'MTD'
declare #Date DATETIME = '2011-08-31'
and I have a big select statement where I'm passing above parameters and it executes the output.
Now I have 10 different dates which I need to pass here each time to see the result.
How can I pass those date to above parameter declare #Date DATETIME how can I hard code it ?
So my desired output will be for those selected dates, give me hint for at least 3 dates ?
Use a table-valued parameter. First, create a type:
CREATE TYPE dbo.Dates AS TABLE(d DATE);
Now your stored procedure can take this type as a parameter:
CREATE PROCEDURE dbo.whatever
#d dbo.Dates READONLY
AS
BEGIN
SET NOCOUNT ON;
SELECT t.columns
FROM dbo.tableName AS t
INNER JOIN #d AS d
ON t.[date] = d.d;
END
GO
Then from your application you can pass this parameter in as a DataTable, for example.