I created a function, now rather passing static value I want to add parameter in the function but after calling function it start throwing an error:
Procedure or function dbo.hello has too many arguments specified.
Function :
Create Function dbo.hello
(#InputstartDate Date, #InputendDate Date)
Returns #attendanceTemp table(STUD_NAME VARCHAR(50),
ATTD_DATE DATE ,
attd_DATEs DATE,
Attendance VARCHAR(20))
As
Begin
Declare #startDate DATE
SET #startDate = #InputstartDate
Declare #endDate Date
SET #endDate = #InputendDate
Declare #dateDifference INT
SET #dateDifference = DATEDIFF(day, #startDate,#endDate) ;
Declare #count INT
SET #count = 0
DECLARE #myTable TABLE (STUD_ID int,
countdd int,
STUD_NAME varchar(50),
AttDate Date
)
While #count <= #dateDifference
Begin
Insert Into #myTable (STUD_ID, countdd, STUD_NAME, AttDate)
Values (1, 123, 'HAIDER', #startDate)
Set #count = #count +1
Set #startDate = DATEADD(day, 1, #startDate)
End
Insert Into #attendanceTemp
Select
tb.STUD_NAME, ATTD_DATE, tb.AttDate,
Case
When att.DETAIL Is Null
Then 'ABSENT'
When att.DETAIL = 'ATTENDACE'
Then 'PRESENT'
End As Attendance
from
#myTable tb
Left Join
ATTENDANCE att on tb.AttDate = att.ATTD_DATE
Where
att.STUD_ID = 1 or att.STUD_ID IS NULL
Return
END
Calling the function:
select *
from dbo.hello('2014-04-01', '2014-04-10');
Error:
Procedure or function dbo.hello has too many arguments specified
Possibly you first created the function with only one parameter.
Then made changes to the 'create function' script, and forgot to deploy?
I would;
1. DROP FUNCTION dbo.hello
2. CREATE FUNCTION dbo.hello, with you script
3. Try executing your function again.
The function seems to work fine (Though I cannot run a full test due to not having table 'ATTENDANCE')
Related
I am moving from Oracle to SQL Server and I am noticing differences regarding assigning variables in a query. I wonder if someone could write me a simple example of how I can do this in SSMS please?
In the example below I am looking to assign the variable #date1 at the beginning of the select statement so that I can simply change the date at the top instead of having to change it several times in the query where #date1 is used several times.
SELECT *
FROM table
where date = #date1
Thanks
Based on your example the syntax would be as follows:
DECLARE #date1 DATETIME
SET #date1 = '2017-01-01 00:00:00.000'
Then reference #date1 in your query as you have above.
More broadly, the syntax is:
DECLARE #<name of variable> <type>
SET #<name of variable> = <value>
-- Simple declares
DECLARE #Variable1 VARCHAR(100)
DECLARE #Variable2 DATE
DECLARE #VariableTable TABLE (
numberColumnName INT,
textColumnName VARCHAR(MAX))
-- Chained declares
DECLARE
#Variable3 VARCHAR(100),
#Variable4 INT
-- Declare with initiation
DECLARE #Variable5 INT = 150
DECLARE #Variable6 DATE = '2018-05-05' -- Implicit conversion (varchar to date)
DECLARE #Variable7 FLOAT = 1945.15 * 1648.12 / #Variable5 -- Expressions can be used
DECLARE #Variable8 INT = (SELECT COUNT(1) FROM sys.objects)
-- Chained declares with initiation
DECLARE
#Variable9 VARCHAR(100) = 'Afla',
#Variable10 INT = 9164 * #Variable5
-- Change variable values (without declaring)
SET #Variable1 = 'Some value'
SET #Variable2 = CONVERT(DATE, GETDATE())
For your example:
DECLARE #DateFilter DATE = '2018-05-16' -- Use ISO standard date format (yyyy-MM-dd) when you hard-code them as literals
SELECT
*
FROM
YourTable AS T
WHERE
T.DateToFilter >= #DateFilter
DECLARE #date1 DATE = '2018-04-11'
This code may be fine, but be aware of dates formats :date (Transact-SQL)
and the need of using either Date, Datetime, or Datetime2.
I am trying to create a stored procedure that does manipulation of parameter passed in before inserting it into my table. One of the columns in my table is called DATE_CHANGED and basically what I gg to do here is to change a passed date parameter like December 1st 2017 to 20171201. This is an int value.
I wrote a stored procedure like this:
CREATE PROCEDURE date_generate
#startDate DATE
AS
BEGIN
DECLARE #DATE_KEY INT
#DATE_KEY = CONVERT(INT, FORMAT(#startDate, 'YYYYMMDD')
INSERT INTO table date_key = #DATE_KEY
END
However I get an error
Incorrect syntax near '#DATE_KEY
Are local variable declared only used for SQL query statement like
select *
from table
where date_key = #DATE_Key?
There is more than one error.
Use SET to assign values to a variable.
Have a look at INSERT statement too.
CREATE PROCEDURE date_generate
#startDate date
AS
BEGIN
DECLARE #DATE_KEY int;
SET #DATE_KEY = CONVERT(int, format(#startDate, 'YYYYMMDD'));
INSERT INTO DATE_CHANGED (date_key)
VALUES (#DATE_KEY);
END
This seems really strange. You don't even need a local variable. Based on your code, you could write:
create procedure date_generate (
#startDate date
) as
begin
insert into table (date_key)
values ( convert(int, format(#startDate, 'YYYYMMDD')) );
end; -- date_generate
Or, I might write:
create procedure date_generate (
#startDate date
) as
begin
insert into table (date_key)
values ( year(#startDate) * 10000 + month(#startDate) * 100 + day(#startDate) );
end;
Why you would have a table with a single date on each row doesn't really make sense to me. Why you would be storing that "date" as an integer also doesn't make sense.
As far as I've understood, your stored procedure accepts a DATE as a parameter, but you need to do an INSERT with an INT.
You can easily convert a DATE to a VARCHAR and then to a INT, this way:
DECLARE #DateASInt INT = CAST(CONVERT(VARCHAR(8), #startDate, 112) AS INT);
So, your stored procedure will be like this:
CREATE PROCEDURE date_generate
#startDate date
AS
BEGIN
INSERT INTO date_key
VALUES (CAST(CONVERT(VARCHAR(8), #startDate, 112) AS INT));
END
I would like to be able to set a parameter of a stored procedure dynamically, based on the results of a SQL query. The stored procedure calculates the distance traveled between a particular date and today. That particular date could be different for each record in the database. (The date is calculated in a separate stored procedure.) See the example.
The stored procedure has two parameters: #DateFrom and #DateTo. #DateFrom should be the date in the DateFrom column, which, as you can see, is different for every record. Is there a way to loop through or something and set the #DateFrom parameter to the value in the DateFrom column for each record? #DateTo will always be today's date. Any help is greatly appreciated.
This is what I got from your question, it's my first answer to a post please excuses typos or code format
USE tempdb
GO
IF OBJECT_ID(N'Tempdb.dbo.#DataTest') IS NULL
BEGIN
CREATE TABLE #DataTest
(
ID INT IDENTITY
,Name VARCHAR(100)
,DateTo DATETIME
,DateFrom DATETIME
)
END
GO
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues1', '20151201',GETDATE() + 1)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues3', '20151203',GETDATE() + 2)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues5', '20151205',GETDATE() + 3)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues7', '20151207',GETDATE() + 4)
INSERT INTO #DataTest (Name,DateTo,DateFrom) VALUES ('DataValues9', '20151209',GETDATE() + 5)
GO
CREATE PROC #CalculateData
(
#DateTo DATETIME,
#DateFrom DATETIME
)
AS
SELECT DATEDIFF(SECOND,#DateTo,#DateFrom) AS DataResult
GO
DECLARE #Count INT = (SELECT MIN(ID) FROM #DataTest)
DECLARE #DateToParam DATETIME
DECLARE #DateFromToParam DATETIME
WHILE #Count IS NOT NULL
BEGIN
SET #DateToParam = (SELECT DateTo FROM #DataTest WHERE ID = #Count)
SET #DateFromToParam = (SELECT DateFrom FROM #DataTest WHERE ID = #Count)
EXEC #CalculateData #DateToParam, #DateFromToParam
SET #Count = (SELECT MIN(ID) FROM #DataTest WHERE ID > #Count)
END
GO
DROP TABLE #DataTest
DROP PROCEDURE #CalculateData
i am working on sql server 2008
i have a stored procedure for getting total amount. while executing this i am getting result
my first stored procedure like this:
alter procedure [dbo].[jaseem_test4]
#carid varchar(50)
as
begin
Declare
#locid integer,
#vtid integer,
#day varchar(20),
#Date date,
#startdate datetime,
#Pdatetime datetime,#Ptime time,
#prkdtime datetime,#pdate date,
#Starttime time,#startloctime varchar(10),
#currenttime varchar(10),#endtime time,
#endloctime varchar(10)
--finding loc_id and vtid
set #locid = (select t.locid
from Transaction_tbl t where Tbarcode=#carid)
set #vtid=(select t.vtid from Transaction_tbl t where TBarcode=#carid)
----------
--finding parked time
set #Pdatetime=(select t.dtime from Transaction_tbl t where Tbarcode=#carid)
--finding location end time
select #endtime=l.EndTime from Location_tbl l where l.Locid=#locid
select #endloctime=convert(Varchar(8), #endtime,108)
select #currenttime=CONVERT(VARCHAR(8),GETDATE(),108)
select #Date=convert(date,getdate())
select #pdate=convert(date,#Pdatetime,108)
select #Ptime=CONVERT(VARCHAR(8),#Pdatetime,108)
declare #prevousdate datetime
select #prevousdate=convert(date,getdate()-1)
declare #LT integer
if #endloctime<#Ptime
begin
select #startdate= cast(#Date as Datetime) + cast(#endloctime as Datetime)
select #prkdtime=cast(#prevousdate as Datetime) + cast(#Ptime as Datetime)
select #LT =datediff(mi,#prkdtime,#startdate)
--select #LT as LT1
end
else
begin
select #LT=datediff(mi,#ptime,#endloctime)
--select #LT as LT
end
declare #PT integer=datediff(mi,#Pdatetime,getdate())
--select #PT as PT
DEclare #daycount integer
if (#LT >= #PT)
begin
set #daycount=1
--select #daycount
end
If (#PT > #LT)
begin
Declare #q Integer ,#q1 float,#modvAL float,#PT1 integer
set #q=1
set #modvAL=1440
set #PT1=#PT-#LT
-- select #PT1 as PT1
if #PT1>#modvAL
begin
set #q1= round((#PT1) / (#modvAL),0)
--select #q1 as q2
end
else
begin
set #q1=1
end
set #q=(#q+#q1)
set #daycount=#daycount*#q
--select #daycount as daycount
end
------------------------------------------------------
declare #days integer,#s varchar(10),#Total integer,
#n integer
,#day1 integer,
#checkWeekend integer,
#Hamount integer,
#Htotel integer, #Namount integer,#startloctime1 varchar(10),#currenttime1 varchar(10),
#Ntotal integer
set #days=0
set #n=0
set #day1=#daycount
set #Htotel=0
set #Ntotal=0
Select #startloctime1= convert(Varchar(8),( select l.StartTime from Location_tbl l where l.Locid=5),108)
select #currenttime1=CONVERT(VARCHAR(8),GETDATE(),108)
while (#days < #day1)
begin
if #day1=1
begin
if #startloctime1>#currenttime1
begin
set #s= datename(dw,getdate()-1)
end
else
begin
set #s= datename(dw,getdate())
end
end
else
begin
select #s=datename(dw,getdate()-#n)
--select #s
end
select #checkWeekend= Weekend from weekends_tbl where weekdays=#s
if #checkWeekend=1
begin
select #hamount= Hamount from locvtypeassign_tbl where
vtid=#vtid and locid=#locid and active=0
set #Htotel=#Htotel+#Hamount
end
else
begin
select #Namount= NAmount from locvtypeassign_tbl where
vtid=#vtid and locid=#locid and active=0
set #Ntotal=#Ntotal+ #Namount
end
set #days=#days+1
set #n= #n+1
set #Total= #Htotel+#Ntotal
end
select #Total as [Total]
end --End main
Go
if i pass carid i am getting out put like this:
Total
100
only for getting this i wrote a stored procedure around 100 lines .in this stored procedure i am just passing one value(Tbarcode)
i have a another stored procedure somthing line this:
Select t.dtime,t.vtid,t.locid
from transaction_tbl t where Tbarcode='4502'
my out put is something like this:
dtime vtid locid
----------------------- ----------- -----------
2014-10-02 23:43:39.453 7 5
i want to add this two stored procedure and i am expecting out put
dtime vtid locid Totalamount
----------------------- ----------- ----------- ------------
2014-10-02 23:43:39.453 7 5 100
i know this i can do by making first stored procedure as function,and return the total amount to second stored procedure.but i fear about execution speed.
if i call function in my stored procedure then my stored procedure execution will get slow right?
without using function is therey any way to get my stored procedure result into second stored proceure??
any help is very appriciable
how i can call my first stored procedure result to seconde stored procedure??
I would use a similar approach as Rahul, but slightly different. To make sure you don't break your existing code which might already be using these 2 procedures, I would do the following:
Step 1. - Extend the first procedure with an optional output parameter as follows (see comments at the end of the lines I've added):
alter procedure [dbo].[jaseem_test4]
#carid varchar(50),
#totalAmount int = null OUTPUT /* the new output parameter which returns the total value */
as
begin
....
set #totalAmount = #Total /* setting the output parameter to the return total value */
select #Total as [Total]
end --End main
Go
Step 2 - call the first procedure with the output parameter from the 2nd procedure - I've borrowed Rahul's code for this
Please note that you just have to add to your 2nd procedure only the lines with a comment:
create procedure sp_another_proc
as
begin
...
declare #totalAmount int /* the total amount variable */
exec jaseem_test4 'InputCaridValue', #totalAmount OUT /* call procedure to get total amount */
....
Select t.dtime,
t.vtid,
t.locid,
#totalAmount as TotalAmount /* add to your final select the #totalAmount variable */
from transaction_tbl t where Tbarcode='4502'
end
GO
All should work just fine.
One approach, assuming that the second procedure also only returns a single row, is to create a 3rd procedure that will call both of the existing ones, capture the output of each, and then select the combination for the real output. The benefit here is that you don't have to modify, in any way, the two existing procedures. This is quite helpful if either, or both, of those existing stored procedures are called by another code and hence a change in behavior might have adverse effects, or at the very least it would create additional complication and code paths to test for.
For example:
DECLARE #JaseemTest4Result TABLE (TotalAmount INT);
DECLARE #Proc2Result TABLE (dtime DATETIME, vtid INT, locid INT);
INSERT INTO #JaseemTest4Result (TotalAmount)
EXEC jaseem_test4 #carid = 25;
INSERT INTO #Proc2Result (dtime, vtid, locid)
EXEC proc2 #Tbarcode = '4502';
SELECT p2r.dtime, p2r.vtid, p2r.locid, jt4.TotalAmount
FROM #JaseemTest4Result jt4
CROSS JOIN #Proc2Result p2r;
Or, if the second stored proc is only for this purpose, you can update it to do only the part from the example above that captures the TotalAmount and then JOIN the real table and the table variable together:
DECLARE #JaseemTest4Result TABLE (TotalAmount INT);
INSERT INTO #JaseemTest4Result (TotalAmount)
EXEC jaseem_test4 #carid = 25;
Select t.dtime, t.vtid, t.locid, jt4.TotalAmount
from transaction_tbl t
CROSS JOIN #JaseemTest4Result jt4
where t.Tbarcode='4502'
Simplest thing you can do is; call your main stored procedure passing the Totalamount value and then display the result like
Main procedure body
exec sp_another_proc 100
In sp_another_proc
create procedure sp_another_proc (#total int)
as
begin
Select t.dtime,
t.vtid,
t.locid,
#total as TotalAmount
from transaction_tbl t where Tbarcode='4502'
end
EDIT:
In your first procedure [dbo].[jaseem_test4] instead of the last line
select #Total as [Total]
Call the second procedure like
exec my_second_procedure #Total
Modify your second procedure to accept a Integer parameter as shown above and then just display it.
I have the function which gets ID and returns date from table if it exists or returns current date if isn't:
CREATE FUNCTION [dbo].[CLOSEDATE] (#ID int)
RETURNS datetime
AS
BEGIN
DECLARE #closed int;
DECLARE #result datetime;
SELECT #result = created_on from dbo.statuses_history
WHERE journalized_id = #ID and new_status = 'Закрыто';
IF #result IS NULL
SELECT #result = GETDATE()
RETURN (DATEADD(dd, 0, DATEDIFF(dd, 0, #result)))
END;
The next queries return correct date from table:
select dbo.closedate(4170)
select dbo.closedate(id) from issues where id = 4170
And the next code update the record correctly (values from table):
DECLARE #d AS datetime
select #d = dbo.closedate(4170)
UPDATE issues SET created_on = #d WHERE issues.id = 4170
But I get current date in the field if I update the record:
UPDATE issues
SET created_on = dbo.CloseDate(id)
WHERE issues.id = 4170
It looks like the ID parameter doesn't pass to the function.
Your tests (that I missed on the first reading, sorry) are enough to make me very confused. It seems that your test results should not be possible.
My only suggestion would be to recode the function and see what happens...
CREATE FUNCTION [dbo].[CLOSEDATE] (#ID int)
RETURNS TABLE
AS
RETURN
SELECT
(DATEADD(dd, 0, DATEDIFF(dd, 0, ISNULL(MAX(created_on), GetDate())))) AS close_date
FROM
dbo.statuses_history
WHERE
journalized_id = #ID
AND new_status = 'Закрыто'
And then...
UPDATE
issues
SET
created_on = fn.close_date
FROM
issues
CROSS APPLY
dbo.CLOSEDATE(id) AS fn
WHERE
issues.id = 4170
Cross Apply is what you looking for I think.