在SQL函数中使用CTE给出错误

时间:2015-07-29 06:18:25

标签: sql-server function

我正在尝试创建一个存储过程,但是我收到了一个错误:

  

函数中包含的Select语句无法将数据返回给客户端。

     

消息156,级别15,状态1,过程fnSc_Channels_GetChannelsUnreadPosts,第39行
  关键字“SET”附近的语法不正确。

有人可以帮帮我吗?

ALTER FUNCTION [dbo].[fnSc_Channels_GetChannelsUnreadPosts]
(
    @FrontEndActorID INT
    , @ChannelActivityFeedActorID INT
)
RETURNS INT
AS
BEGIN
     DECLARE    @return_value AS INT

     --EXEC @return_value = [dbo].[iD_Channels_Channel_GetUnreadPostCount]
     --     @FrontEndActorID = 7,
     --     @ChannelActivityFeedActorID = 13

     -- RETURN @return_value

    DECLARE @LastReadTime DATETIME

    SELECT @LastReadTime = LastVisitTime
    FROM iDtbl_Channels_ChannelMemberLastVisitTime WITH(NOLOCK)
    WHERE
        ChannelActivityFeedActorID = @ChannelActivityFeedActorID 
        AND FrontEndActorID = @FrontEndActorID

    ;WITH ChannelFeedActors AS
    (
        SELECT A.ActivityFeedProfileID
        FROM iDtbl_Channels_Channel C WITH(NOLOCK) 
        INNER JOIN iDtbl_FileSystem_FrontEndActor A WITH(NOLOCK) ON C.OwnerFrontEndActorID = A.FrontEndActorID
        WHERE
            C.OwnerFrontEndActorID = @FrontEndActorID

        UNION ALL

        SELECT @ChannelActivityFeedActorID
)

SET @return_value = (SELECT ISNULL(COUNT(DISTINCT ActivityID), 0) UnreadPosts
FROM ChannelFeedActors A
INNER JOIN iDtbl_ActivityFeed_ActivityFeed AF WITH(NOLOCK) ON A.ActivityFeedProfileID = AF.ActivityFeedActorID
WHERE
    (
        @LastReadTime IS NULL
        OR DateAdded > @LastReadTime
    )
    AND ActivityTypeID <> 6
    AND FromActorID <> @FrontEndActorID )

    RETURN @return_value
END

1 个答案:

答案 0 :(得分:1)

您必须使用SELECT代替SET

ALTER FUNCTION [dbo].[fnSc_Channels_GetChannelsUnreadPosts]
(
    @FrontEndActorID INT
    , @ChannelActivityFeedActorID INT
)
RETURNS INT
AS
BEGIN

DECLARE @return_value AS INT

DECLARE @LastReadTime DATETIME

SELECT @LastReadTime = LastVisitTime
FROM iDtbl_Channels_ChannelMemberLastVisitTime WITH(NOLOCK)
WHERE
    ChannelActivityFeedActorID = @ChannelActivityFeedActorID 
    AND FrontEndActorID = @FrontEndActorID

;WITH ChannelFeedActors AS(
    SELECT A.ActivityFeedProfileID
    FROM iDtbl_Channels_Channel C WITH(NOLOCK) 
    INNER JOIN iDtbl_FileSystem_FrontEndActor A WITH(NOLOCK)
    ON C.OwnerFrontEndActorID = A.FrontEndActorID
    WHERE
        C.OwnerFrontEndActorID = @FrontEndActorID
    UNION ALL
    SELECT @ChannelActivityFeedActorID
)
-- Instead of using SET, use SELECT
-- Remove the column alias UnreadPosts
SELECT @return_value = ISNULL(COUNT(DISTINCT ActivityID), 0)
FROM ChannelFeedActors A
INNER JOIN iDtbl_ActivityFeed_ActivityFeed AF WITH(NOLOCK)  
ON A.ActivityFeedProfileID = AF.ActivityFeedActorID
WHERE
    (
        @LastReadTime IS NULL
        OR DateAdded > @LastReadTime
    )
    AND ActivityTypeID <> 6
    AND FromActorID <> @FrontEndActorID

RETURN @return_value

END

至于错误:

  

Msg 319,Level 15,State 1,Procedure   fnSc_Channels_GetChannelsUnreadPosts,第41行附近的语法不正确   关键字&#39; with&#39;。如果此语句是公用表表达式,则为   xmlnamespaces子句或更改跟踪上下文子句,前一个   声明必须以分号结束。

您必须使用分号在CTE之前终止先前的语句。

DECLARE @var INT;

WITH CTE AS(...)

然而,大多数人只是用;开始他们的CTE声明:

DECLARE @var INT

;WITH CTE AS(...)