3

私はこの手順を持っています

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 です

4

4 に答える 4

3

構文に基づいて、今のところ 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と組み合わせると、ステートメントが効果的に実行されます。 (user.isTrade が になる可能性がある場合は、より似たものに変更する必要があることに注意してください。)WHEREIFNULLuser.isTrade <> 1ISNULL(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
  • NULL の場合group_id、最初の結合は決して成功しません。
  • 次に、2 つの IF ブロックが によってシミュレートされますOR
于 2012-11-01T09:33:29.927 に答える
1

PROC の結果を一時テーブルに保存できます。

INSERT INTO #temptbl EXEC [dbo].GetHerdByUserProc(80)
于 2012-11-01T09:21:22.910 に答える
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を参照してください。

于 2012-11-01T09:21:38.867 に答える
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
于 2012-11-01T18:54:56.147 に答える