ALTER FUNCTION [dbo].[FSmapping] (
#runID as bigInt,
#TypMap as char(1)
)
RETURNS TABLE
AS
RETURN
IF (#TypMap ='C')
BEGIN
SELECT b.[A/C],g.accountNumber, b.[Process], g.[endingBalanceLC], g.beginningBalanceLC
FROM table1 g
LEFT JOIN table2 b ON b.[Acc2]=g.Account_Synt
where RunID = #runID
END
I am trying to implement a table function in SQL. Basically it should have 3 more IFs and the only thing that's going to switch is the table2, from table2-4 based on inputs C I R S. The error is the IF statement, I know that something is missing, I am having a hard time implementing some sort of a switch function with table as a return value. The Select works flawlessly without the IF syntax, it also says errors on the two variables inside the IF
Must declare the scalar variable runID and TypMap
You need to change your query as multi-statement table-valued functions so your function has to like as below:
CREATE OR ALTER FUNCTION [dbo].[FSmapping] (
#runID as bigInt,
#TypMap as char(1)
)
RETURNS #Table1JoinTable2
TABLE (
--table definition here
Col1 VARCHAR(10)
)
AS
BEGIN
IF (#TypMap ='C')
BEGIN
INSERT INTO #Table1JoinTable2
SELECT #TypMap
--Put select query SELECT b.[A/C],g.accountNumber, b.[Process], g.[endingBalanceLC], g.beginningBalanceLC
--FROM table1 g
--LEFT JOIN table2 b ON b.[Acc2]=g.Account_Synt
--where RunID = #runID
END
IF (#TypMap ='I')
BEGIN
INSERT INTO #Table1JoinTable2
SELECT #TypMap
--Put your select query
END
IF (#TypMap ='I')
BEGIN
INSERT INTO #Table1JoinTable2
SELECT #TypMap
--Put your select query
END
IF (#TypMap ='R')
BEGIN
INSERT INTO #Table1JoinTable2
SELECT #TypMap
--Put your select query
END
IF (#TypMap ='S')
BEGIN
INSERT INTO #Table1JoinTable2
SELECT #TypMap
--Put your select query
END
RETURN
END
If TypMap does not come C, what will the function return?
i think u need 'ELSE'.
IF Boolean_expression
BEGIN
-- Statement block executes when the Boolean expression is TRUE
END
ELSE
BEGIN
-- Statement block executes when the Boolean expression is FALSE
END
Related
I try to create stored procedure, but I had syntax error and I don't know what to change. I want to receive number from the select query to the "#cartypeID" for insert the car type number the the insert code below.
create PROCEDURE AddCar (#CarFleetID int,#CarModelName nvarchar(50),#CarNumber nvarchar(50),#CurrentMiles int,#ImageFileName nvarchar(50),#IsOk2Rent bit)
AS
IF (SELECT COUNT(1) FROM CarFleet WHERE CarFleetID =#CarFleetID ) = 1
BEGIN
RETURN -1
END ELSE
BEGIN
declare #cartypeID int
#cartypeID= select CarFleet.CarFleetID
from CarFleet join CarTypes on CarFleet.CarTypeID=CarTypes.CarTypeID join CarModels on CarTypes.CarModelID=CarModels.CarModelID
where #CarModelName=CarModels.CarModelName
INSERT INTO CarFleet(CarFleetID,CarTypeID,CarNumber,CurrentMiles,ImageFileName,IsOk2Rent)
VALUES(#CarFleetID, #cartypeID, #CarNumber,#CurrentMiles,#ImageFileName,#IsOk2Rent)
END
I think
create PROCEDURE AddCar (#CarFleetID int,#CarModelName nvarchar(50),#CarNumber nvarchar(50),#CurrentMiles int,#ImageFileName nvarchar(50),#IsOk2Rent bit)
AS
IF (SELECT COUNT(1) FROM CarFleet WHERE CarFleetID =#CarFleetID ) = 1
BEGIN
RETURN -1
END ELSE
BEGIN
INSERT INTO CarFleet (
CarFleetID
,CarTypeID
,CarNumber
,CurrentMiles
,ImageFileName,IsOk2Rent)
select
CarFleet.CarFleetID
,#cartypeID
,#CarNumber
,#CurrentMiles
,#ImageFileName,#IsOk2Rent
from CarFleet
join CarTypes on CarFleet.CarTypeID=CarTypes.CarTypeID
join CarModels on CarTypes.CarModelID=CarModels.CarModelID
where #CarModelName=CarModels.CarModelName
END
I created one function, That function return the table values like below
CREATE FUNCTION dbo.splitText(#strArgs VARCHAR(4000))
RETURNS #tab TABLE
(
[Key] VARCHAR(255) NOT NULL,
Value VARCHAR(4000) NOT NULL
)
AS
BEGIN
INSERT INTO #tab VALUES('Key1', 'Value1')
INSERT INTO #tab VALUES('Key2', 'Value2')
RETURN
END
GO
OUtput:
Key Value
*************
Key1 Value1
Key2 Value2
The second function i need,is to return the table values from the above fuction.
CREATE FUNCTION dbo.TableValuedParameterExample11()
RETURNS #TmpTable1 table (Value VARCHAR(4000) NOT NULL)
AS
BEGIN
DECLARE #StateDescp VARCHAR(250)
Select * into TmpTable1 from (Select value from dbo.Splittext('Test')) aa
RETURN
END
GO
after finishing the functions,i am running the below query.
Select * from TmpTable1.
Output i need
Value
********
Value1
Value2
I need this out put.
But I got error
Invalid use of a side-effecting operator 'SELECT INTO' within a function.
When you write select * into [table]... you must be sure the [table] doesnot exist. use insert into [table] select ... instead. also, you need a # when you deal with variable or function table:
CREATE FUNCTION dbo.TableValuedParameterExample11()
RETURNS #TmpTable1 table (Value VARCHAR(4000) NOT NULL)
AS
BEGIN
DECLARE #StateDescp VARCHAR(250)
INSERT INTO
#TmpTable1([Value])
SELECT
value
FROM
dbo.SplitArgs('Test')) aa
RETURN
END
GO
I have a stored procedure that takes in two parameters. I can execute it successfully in Server Management Studio. It shows me the results which are as I expect. However it also returns a Return Value.
It has added this line,
SELECT 'Return Value' = #return_value
I would like the stored procedure to return the table it shows me in the results not the return value as I am calling this stored procedure from MATLAB and all it returns is true or false.
Do I need to specify in my stored procedure what it should return? If so how do I specify a table of 4 columns (varchar(10), float, float, float)?
A procedure can't return a table as such. However you can select from a table in a procedure and direct it into a table (or table variable) like this:
create procedure p_x
as
begin
declare #t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert #t values('a', 1,1,1)
insert #t values('b', 2,2,2)
select * from #t
end
go
declare #t table(col1 varchar(10), col2 float, col3 float, col4 float)
insert #t
exec p_x
select * from #t
I do this frequently using Table Types to ensure more consistency and simplify code. You can't technically return "a table", but you can return a result set and using INSERT INTO .. EXEC ... syntax, you can clearly call a PROC and store the results into a table type. In the following example I'm actually passing a table into a PROC along with another param I need to add logic, then I'm effectively "returning a table" and can then work with that as a table variable.
/****** Check if my table type and/or proc exists and drop them ******/
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'returnTableTypeData')
DROP PROCEDURE returnTableTypeData
GO
IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = 'myTableType')
DROP TYPE myTableType
GO
/****** Create the type that I'll pass into the proc and return from it ******/
CREATE TYPE [dbo].[myTableType] AS TABLE(
[someInt] [int] NULL,
[somenVarChar] [nvarchar](100) NULL
)
GO
CREATE PROC returnTableTypeData
#someInputInt INT,
#myInputTable myTableType READONLY --Must be readonly because
AS
BEGIN
--Return the subset of data consistent with the type
SELECT
*
FROM
#myInputTable
WHERE
someInt < #someInputInt
END
GO
DECLARE #myInputTableOrig myTableType
DECLARE #myUpdatedTable myTableType
INSERT INTO #myInputTableOrig ( someInt,somenVarChar )
VALUES ( 0, N'Value 0' ), ( 1, N'Value 1' ), ( 2, N'Value 2' )
INSERT INTO #myUpdatedTable EXEC returnTableTypeData #someInputInt=1, #myInputTable=#myInputTableOrig
SELECT * FROM #myUpdatedTable
DROP PROCEDURE returnTableTypeData
GO
DROP TYPE myTableType
GO
Consider creating a function which can return a table and be used in a query.
https://msdn.microsoft.com/en-us/library/ms186755.aspx
The main difference between a function and a procedure is that a function makes no changes to any table. It only returns a value.
In this example I'm creating a query to give me the counts of all the columns in a given table which aren't null or empty.
There are probably many ways to clean this up. But it illustrates a function well.
USE Northwind
CREATE FUNCTION usp_listFields(#schema VARCHAR(50), #table VARCHAR(50))
RETURNS #query TABLE (
FieldName VARCHAR(255)
)
BEGIN
INSERT #query
SELECT
'SELECT ''' + #table+'~'+RTRIM(COLUMN_NAME)+'~''+CONVERT(VARCHAR, COUNT(*)) '+
'FROM '+#schema+'.'+#table+' '+
' WHERE isnull("'+RTRIM(COLUMN_NAME)+'",'''')<>'''' UNION'
FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = #table and TABLE_SCHEMA = #schema
RETURN
END
Then executing the function with
SELECT * FROM usp_listFields('Employees')
produces a number of rows like:
SELECT 'Employees~EmployeeID~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("EmployeeID",'')<>'' UNION
SELECT 'Employees~LastName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("LastName",'')<>'' UNION
SELECT 'Employees~FirstName~'+CONVERT(VARCHAR, COUNT(*)) FROM dbo.Employees WHERE isnull("FirstName",'')<>'' UNION
You can use an out parameter instead of the return value if you want both a result set and a return value
CREATE PROCEDURE proc_name
#param int out
AS
BEGIN
SET #param = value
SELECT ... FROM [Table] WHERE Condition
END
GO
I had a similar situation and solved by using a temp table inside the procedure, with the same fields being returned by the original Stored Procedure:
CREATE PROCEDURE mynewstoredprocedure
AS
BEGIN
INSERT INTO temptable (field1, field2)
EXEC mystoredprocedure #param1, #param2
select field1, field2 from temptable
-- (mystoredprocedure returns field1, field2)
END
The Status Value being returned by a Stored Procedure can only be an INT datatype. You cannot return other datatypes in the RETURN statement.
From Lesson 2: Designing Stored Procedures:
Every stored procedure can return an integer value known as the
execution status value or return code.
If you still want a table returned from the SP, you'll either have to work the record set returned from a SELECT within the SP or tie into an OUTPUT variable that passes an XML datatype.
HTH,
John
Though this question is very old but as a new in Software Development I can't stop my self to share what I have learnt :D
Creation of Stored Procedure:
CREATE PROC usp_ValidateUSer
(
#UserName nVARCHAR(50),
#Password nVARCHAR(50)
)
AS
BEGIN
IF EXISTS(SELECT '#' FROM Users WHERE Username=#UserName AND Password=#Password)
BEGIN
SELECT u.UserId, u.Username, r.UserRole
FROM Users u
INNER JOIN UserRoles r
ON u.UserRoleId=r.UserRoleId
END
END
Execution of Stored Procedure:
(If you want to test the execution of Stored Procedure in SQL)
EXEC usp_ValidateUSer #UserName='admin', #Password='admin'
The Output:
create procedure PSaleCForms
as
begin
declare
#b varchar(9),
#c nvarchar(500),
#q nvarchar(max)
declare #T table(FY nvarchar(9),Qtr int,title nvarchar (max),invoicenumber nvarchar(max),invoicedate datetime,sp decimal 18,2),grandtotal decimal(18,2))
declare #data cursor
set #data= Cursor
forward_only static
for
select x.DBTitle,y.CurrentFinancialYear from [Accounts Manager].dbo.DBManager x inner join [Accounts Manager].dbo.Accounts y on y.DBID=x.DBID where x.cfy=1
open #data
fetch next from #data
into #c,#b
while ##FETCH_STATUS=0
begin
set #q=N'Select '''+#b+''' [fy], case cast(month(i.invoicedate)/3.1 as int) when 0 then 4 else cast(month(i.invoicedate)/3.1 as int) end [Qtr], l.title,i.invoicenumber,i.invoicedate,i.sp,i.grandtotal from ['+#c+'].dbo.invoicemain i inner join ['+#c+'].dbo.ledgermain l on l.ledgerid=i.ledgerid where (sp=0 or stocktype=''x'') and invoicetype=''DS'''
insert into #T exec [master].dbo.sp_executesql #q
fetch next from #data
into #c,#b
end
close #data
deallocate #data
select * from #T
return
end
Here's an example of a SP that both returns a table and a return value. I don't know if you need the return the "Return Value" and I have no idea about MATLAB and what it requires.
CREATE PROCEDURE test
AS
BEGIN
SELECT * FROM sys.databases
RETURN 27
END
--Use this to test
DECLARE #returnval int
EXEC #returnval = test
SELECT #returnval
When I execute my code it works but my data repeats itself. The print is just to see what it gets.
DECLARE #Variable1 NVARCHAR(MAX)
DECLARE #Variable2 NVARCHAR(MAX)
DECLARE #Variable3 NVARCHAR(MAX)
CREATE TABLE #Temp1 (MAI_ID BIGINT, FUN_ID BIGINT)
CREATE TABLE #tmp2 (MAI_ID BIGINT, Variable1 NVARCHAR(MAX),Variable2 NVARCHAR(MAX), Variable3 NVARCHAR(MAX))
INSERT INTO #Temp1
SELECT TOP 10 ISD_MainID, ISNULL(ISD_FUNID,0)
FROM [dev_SAB_EM].[dbo].[SiteDetails]
ORDER BY ISD_ID DESC
DECLARE #MAI_ID BIGINT
DECLARE #FUN_ID BIGINT
WHILE (SELECT COUNT(MAI_ID) FROM #Temp1) <> 0
BEGIN
SELECT TOP 1 #MAI_ID = MAI_ID, #FUN_ID = FUN_ID FROM #Temp1
PRINT #MAI_ID
PRINT #FUN_ID
SELECT #Variable1 = ISNULL(FUN_Name,'') FROM [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] (#FUN_ID) WHERE FUN_Level = 1
SELECT #Variable2 = ISNULL(FUN_Name,'') FROM [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] (#FUN_ID) WHERE FUN_Level = 2
SELECT #Variable3 = ISNULL(FUN_Name,'') FROM [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] (#FUN_ID) WHERE FUN_Level = 3
INSERT INTO #tmp2(MAI_ID, Variable1, Variable2, Variable3)
SELECT #MAI_ID, #Variable1, #Variable2, #Variable3
DELETE FROM #Temp1 WHERE MAI_ID = #MAI_ID AND FUN_ID = #FUN_ID
END
SELECT * FROM #tmp2
DROP TABLE #Temp1
DROP TABLE #tmp2
fx_GetFUNStructureCTE_Asc
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fx_GetFUNStructureCTE_Asc] (#param_FUNID int)
RETURNS #FUN_Names table
(
[Level_Label] nvarchar(255),
[FUN_Name] nvarchar(255),
[FUN_Level] int,
[FUN_ID] int
)
AS
BEGIN
with cte([Level_Label],[FUN_Name],[FUN_Level],[FUN_ID],[FUN_FUNID]) as
(
select ful1.FUL_Name,fu1.FUN_Name,fu1.FUN_Level,fu1.FUN_ID,fu1.FUN_FUNID
from FunctionalUnits fu1
inner join FunctionalUnitLevels ful1 on ful1.FUL_Level=fu1.FUN_Level
where fu1.FUN_ID=#param_FUNID
union all
select ful2.FUL_Name,fu2.FUN_Name,fu2.FUN_Level,fu2.FUN_ID,fu2.FUN_FUNID
from FunctionalUnits fu2
inner join FunctionalUnitLevels ful2 on ful2.FUL_Level=fu2.FUN_Level
inner join CTE a on a.FUN_FUNID=fu2.FUN_ID
)
insert into #FUN_Names
([Level_Label],[FUN_Name],[FUN_Level],[FUN_ID])
(select [Level_Label],[FUN_Name],[FUN_Level],[FUN_ID] from cte
where exists (select FUA_isActive from FunctionalUnitsActive where FUA_isActive=1))
return
RETURN
END
GO
Any suggestions or anything that can hep me?
Ok I've added fx_GetFUNStructureCTE_Asc
Considering the informations you gave, besides what #Lamak said, it also may depend on what the the field ISD_FUNID values has on [dev_SAB_EM].[dbo].[SiteDetails] table. If they are all the same on every record then there's no problem with your code...
But, it's a basic assumption...
And, assuming what you said on your comment as the value of ISD_FUNID being NULL, what may be happening is this: when all the value of the field FUN_ID are 0 on table #Temp1 what will happen when you execute the query on the function [dev_SAB_Man].[dbo].[fx_GetFUNStructureCTE_Asc] is that all rows will loop while the assignment occurs, setting the variables values to the last one returned by the function.
It'll make all the variables values be the same for all #tmp2 rows. You may need to improve the function call to return just one value.
I have faced a problem using rowcount in function in sql server 2000.
It shows an error like Invalid use of 'UNKNOWN TOKEN' within a function.
MY function is like this.
ALTER Function fnc_GetOpenShiftWorkID (#EMP_ID int,#Counter int,#date Datetime) returns int as
BEGIN
SET ROWCOUNT #Counter
declare #result int
if exists(select * from tbl_org_workinghrs WHERE EMP_ID=#EMP_ID and SDATE=#DATE)
BEGIN
select #result= WORK_ID
from tbl_org_working_hrs work_hrs
inner join tbl_org_shift_group sgroup on sgroup.WH_ID=work_hrs.WORK_ID
inner join tbl_org_workinghrs workhrs on workhrs.GROUP_ID=sgroup.GROUP_ID
WHERE EMP_ID=#EMP_ID
and SDATE=#DATE
order by
IN_START
END
ELSE
BEGIN
if exists(select * from tbl_org_workinghrs where EMP_ID=0)
BEGIN
select #result=WORK_ID
from tbl_org_working_hrs
WHERE IS_DEFAULTSHIFT=1
END
END
return #result
END
You want to get the value of the n'th row ordered by IN_START.
From SQL Server 2005 later you could use top(n) or row_number().
In SQL Server 2000 you can use a table variable with an identity ID field as a temp storage.
Something like this.
declare #T table
(
ID int identity,
WORK_ID int
)
insert into #T (WORK_ID)
select WORK_ID
from tbl_org_working_hrs work_hrs
inner join tbl_org_shift_group sgroup
on sgroup.WH_ID=work_hrs.WORK_ID
inner join tbl_org_workinghrs workhrs
on workhrs.GROUP_ID=sgroup.GROUP_ID
where EMP_ID=#EMP_ID and
SDATE=#DATE
order by IN_START
select #result = WORK_ID
from #T
where ID = #Counter