Reputation: 9152
I have this procedure
ALTER PROCEDURE [dbo].GetHerdByUserProc(@user int)
As
begin
Declare
@GroupId uniqueidentifier,
@UserTrade bit
Set @GroupId = (select tbUser.group_id from tbUser where Userid = @user)
Set @UserTrade = (select tbUser.isTrade from tbUser where Userid = @user)
if @GroupId IS NOT NULL and @UserTrade = '1'
Begin
select HerdId from tbUserHerds where tbUserHerds.UserId in (select Userid from tbUser where tbUser.Group_Id = @GroupId)
return;
END
If @GroupId IS NOT NULL
Begin
select HerdId from tbUserHerds where tbUserHerds.UserId = @user
return;
End
return;
End
It returns a list correctly except I would also like to run a query on the list that is returned and as far as I am aware I cannot write a query such as
Select * from GetHerdByUserProc 80
So I am looking the best way to convert this to a table-valued query.
I have changed the alter to say 'Create Function x(@user int) Returns Table As'
But that does not seam to work it starts screaming errors at me.
Any ideas? The Database Server is MSSQL2008
Upvotes: 3
Views: 11911
Reputation: 2780
you can simply write sql query using CASE statement . CASE statement is easiest way to handle Conditional Queries .
Declare @GroupId uniqueidentifier,@UserTrade bit
select HerdId
from tbUserHerds
where
1 = CASE
WHEN (select tbUser.group_id from tbUser where Userid = @user) IS NOT NULL
THEN
CASE
WHEN tbUserHerds.UserId = @user THEN 1
ELSE 0
END
WHEN
(select tbUser.group_id from tbUser where Userid = @user) IS NOT NULL and (select tbUser.isTrade from tbUser where Userid = @user) = '1'
THEN
CASE
WHEN tbUserHerds.UserId in (select Userid from tbUser where tbUser.Group_Id = (select tbUser.group_id from tbUser where Userid = @user)) THEN 1
ELSE 0
END
END
Upvotes: 0
Reputation: 86765
Based on your Syntax, I'm going to assume SQL Server for now.
From BOL the Syntax for an inline function should be...
--Transact-SQL Inline Table-Valued Function Syntax
CREATE FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type
[ = default ] [ READONLY ] }
[ ,...n ]
]
)
RETURNS TABLE
[ WITH <function_option> [ ,...n ] ]
[ AS ]
RETURN [ ( ] select_stmt [ ) ]
[ ; ]
With this format, you can not use SET, DECLARE, IF, etc
. All you can use is a single SQL Statement. [If you need to use program flow, look to a multi-statement table valued function.]
It's a separate topic, but Inline Table Valued Functions have many performance efficiencies over their Multi-Statement equivilents. Nearly always, if you can do it Inline, you should do so.
As it happens, you can write your logic without the IF
statements, and use just a single SQL Statement. This gives the following Inline Table Valued Function...
CREATE FUNCTION [dbo].GetHerdByUserProc(@user int)
RETURNS TABLE
RETURN
SELECT
herd.HerdID
FROM
tbUser AS user
INNER JOIN
tbUser AS group
ON group.group_id = user.group_id
INNER JOIN
tbUserHerds AS herd
ON herd.UserID = group.UserID
WHERE
user.userID = @userID
AND user.isTrade = 1
AND user.group_id IS NOT NULL
UNION ALL
SELECT
herd.HerdID
FROM
tbUser AS user
INNER JOIN
tbUserHerds AS herd
ON herd.UserID = user.UserID
WHERE
user.userID = @userID
AND user.isTrade <> 1
AND user.group_id IS NOT NULL
The UNION ALL
combined with the WHERE
clauses effectively does your IF
statements for you. (Do note, if user.isTrade can be NULL
, you need to change user.isTrade <> 1
to something more like ISNULL(user.isTrade, 0) <> 1
.)
Potentially, you could even simplify this down to a single query, though I would test it to see if it's actually any more efficient or not...
RETURN
SELECT
herd.HerdID
FROM
tbUser AS user
INNER JOIN
tbUser AS group
ON (group.group_id = user.group_id AND user.isTrade = 1)
OR (group.user_id = user.userID)
INNER JOIN
tbUserHerds AS herd
ON herd.UserID = group.UserID
WHERE
user.userID = @userID
group_id
is NULL, the first join will never succeed. OR
. Upvotes: 3
Reputation: 51504
You need to define the structure of the table in the definition and then insert values into the declare table variable...
create function x
(
@user int
)
returns @t
(
herdid int
)
as
begin
insert @t (herdid)
select HerdId from tbUserHerds where tbUserHerds.UserId = @user
-- or whatever...
return
end
See http://msdn.microsoft.com/en-us/library/ms191165(v=sql.105).aspx
Upvotes: 1
Reputation: 9572
You could store the results of the PROC in a temp table:
INSERT INTO #temptbl EXEC [dbo].GetHerdByUserProc(80)
Upvotes: 1