我有这个程序
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
它正确返回一个列表,除了我还要在返回的列表上运行查询,据我所知,我不能写一个查询,如
Select * from GetHerdByUserProc 80
所以我正在寻找将其转换为表值查询的最佳方法。
我已将更改更改为'Create Function x(@user int) Returns Table As'
但这并没有结束工作,它开始尖叫我的错误。
有什么想法吗?数据库服务器是MSSQL2008
答案 0 :(得分:2)
根据你的语法,我现在要假设SQL Server。
从BOL开始,内联函数的语法应为......
--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 [ ) ]
[ ; ]
使用此格式, 无法 使用SET, DECLARE, IF, etc
。您可以使用的只是一个SQL语句。 [如果您需要使用程序流程,请查看多语句表值函数。]
这是一个单独的主题,但内联表值函数与其多语句等效项相比具有许多性能效率。几乎总是,如果你能做到内联,你应该这样做。
实际上,您可以在没有IF
语句的情况下编写逻辑,并且只使用一个SQL语句。这给出了以下内联表值函数...
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
UNION ALL
结合WHERE
条款有效地为您执行IF
语句。 (请注意,如果user.isTrade可以为NULL
,则需要将user.isTrade <> 1
更改为更像ISNULL(user.isTrade, 0) <> 1
的内容。)
潜在地,您甚至可以将其简化为单个查询,但我会测试它以确定它是否实际上更高效...
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
为NULL,则第一次连接将永远不会成功。 OR
模拟两个IF块。 答案 1 :(得分:1)
您可以将PROC的结果存储在临时表中:
INSERT INTO #temptbl EXEC [dbo].GetHerdByUserProc(80)
答案 2 :(得分:1)
您需要在定义中定义表的结构,然后将值插入声明表变量...
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
请参阅http://msdn.microsoft.com/en-us/library/ms191165(v=sql.105).aspx
答案 3 :(得分:0)
您可以使用CASE语句简单地编写SQL查询。 CASE语句是处理条件查询的最简单方法。
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