2017-02-08 8 views
0

"ThreadID"と "UserID"の2つのパラメータをとり、2つの値を持つテーブルを返します。テーブル値関数を作成しようとしています。 "HasVoted"と "IsUpvote"。それが動作するはずのように私にテーブル値関数のキーワード 'IF'の近くの構文が正しくありません

CREATE FUNCTION HasVotedIsUpvote 
( 
    @ThreadID int, 
    @UserID int 
) 

RETURNS @returnTable TABLE 
(
    HasVoted int NOT NULL, 
    IsUpvote int NOT NULL 
) 
AS 
BEGIN 

DECLARE @HasVoted bit 
DECLARE @IsUpvote bit 


SELECT @HasVoted = 
    CASE WHEN EXISTS (SELECT tv.IsUpvote 
    FROM dbo.ThreadVotes as tv 
    WHERE tv.ThreadID = @ThreadID 
    AND tv.UserID = @UserID) 
    THEN CAST(1 AS BIT) 
    ELSE CAST(0 AS BIT) 

IF @HasVoted = 1 
BEGIN 
    SELECT @IsUpvote = 
    (SELECT tv.IsUpvote 
    FROM dbo.ThreadVotes as tv 
    WHERE tv.ThreadID = @ThreadID 
    AND tv.UserID = @UserID) 
END 

BEGIN 
    INSERT @returnTable 
    SELECT @HasVoted, @IsUpvote 
END 

RETURN 
END 
GO 

これがようだが、私は、エラーメッセージが表示されます。

Msg 156, Level 15, State 1, Procedure HasVotedIsUpvote, Line 38 [Batch Start Line 4] 
Incorrect syntax near the keyword 'IF'. 
+2

ELSE CAST(0 BIT AS)END – Snowlockk

+0

うわー、それは速かったが、それは動作します:

これを試してみてください!どうもありがとう! –

+0

これは非常に非効率な理由/機能の実装であるようです。これは、非常に "手続き的"なので、良いSQLが(セットベースの)ものとは逆のものです。これは一般にどのように使用されますか? –

答えて

0

欠落ENDキーワードは

SELECT @HasVoted = 
    CASE WHEN EXISTS (SELECT tv.IsUpvote 
    FROM dbo.ThreadVotes as tv 
    WHERE tv.ThreadID = @ThreadID 
    AND tv.UserID = @UserID) 
    THEN CAST(1 AS BIT) 
    ELSE CAST(0 AS BIT) 
    END // <-- This one 

幸運であります

2

あなたCASEの表現が欠けているようですEND

SELECT @HasVoted = 
    CASE 
     WHEN EXISTS (SELECT tv.IsUpvote 
        FROM dbo.ThreadVotes as tv 
        WHERE tv.ThreadID = @ThreadID 
          AND tv.UserID = @UserID) 
      THEN CAST(1 AS BIT) 
     ELSE CAST(0 AS BIT) 
    END -- Should be used here 
0

UDFには、単一のSELECTステートメント以外のANYステートメントを含めることはできません。 UDF内のロジックを使用する外部SQLステートメントに変換して、結合されたSQLを照会プロセッサーで処理し、組み合わせたコンパイル済みプロセスとしてプロセス・キャッシュに保管できるようにする必要があります。あなたが書いたのは、インラインのテーブル値のUDFではありません。通常の手続き型UDF(テーブル変数を返すようにコード化されています)で、実行するたびに再コンパイルされます。

AN inlineテーブル値UDF otohは、その中のSQLが使用されているステートメントまたはプロシージャのSQLと結合されているため、一度コンパイルされた単一の結合SQL文を作成するため、プロシージャキャッシュに格納され、繰り返し使用されます。

CREATE FUNCTION HasVotedIsUpvote 
(@ThreadID int, @UserID int) 
RETURNS TABLE 
AS 
return 
    (Select count(*) hasVoted, 
     Sum(isUpvote) isUpvote 
    from ThreadVotes 
    where ThreadID = @ThreadID 
     and UserID = @UserID) 
+0

テーブル値のUDFには、インラインとマルチステートメントの2種類があります。あなたのアサーション(「単一のSelect Statement以外のStatemnentを含むことはできません」)は、インラインではtrueですが、(多分、名前からは明らかに)multistatementには当てはまりません。 –

+0

はい、@ダミアン、あなたは私を編集モードで捕まえました。私はそれを書いている間、私が終わるまで表示されないように私の答えをロックすることができないことが嫌いです。完全な思考は初めて完全に私の指から来ることはありません。 –

関連する問題