1

SQL は私の得意分野ではありませんが、このストアド プロシージャを最適化しようとしています。テーブル値関数に変更しようとした複数のスカラー値関数がありました。これは、より効率的な方法であると多くの場所で読んだためです。そして今、私はそれらを作成しましたが、実装方法がよくわかりません。または、正しく作成しなかっただけかもしれません。

これは私が呼び出している関数です。

Alter FUNCTION [IsNotSenateActivityTableValue]
(
    @ActivityCode int,
    @BillId int,
    @TextToDisplay varchar(max)
)
returns @T table(result varchar(max))
as
begin
DECLARE @result varchar(max);
    declare @countcodes int;


declare @ishousebill int;

select @ishousebill = count(billid)
from BillMaster
where BillID = @BillID and Chamber = 'H'

If (@ishousebill = 0)
begin


SELECT @countcodes = count([ActivityCode])
      FROM [HouseCoreData].[dbo].[ActivityCode]
      where ActivityDescription not like '%(H)%' and ActivityType = 'S'
      and [ActivityCode] = @ActivityCode

if (@countcodes = 0)
begin
    set @result = 'test'
   end
  else
     begin
        set @result = 'test2'
    end
end
else
begin
    set @result = @TextToDisplay
end
RETURN 

END

そして、これが私が彼らをこのように呼ぼうとしていた方法です。私はそれらを一番上に置くことができることを望んでいますが、実際には機能するものは何でも良いでしょう.

SELECT distinct       
      ActionDates.result as ActionDate
      ,ActivityDescriptions.result as ActivityDescription        
  FROM BillWebReporting.vwBillDetailWithSubjectIndex as vw
  left outer join [BillWebReporting].[HasHouseSummary] as HasSummary on vw.BillID = HasSummary.BillID
  outer APPLY dbo.IsNotSenateActivityDateTableValue(ActivityCode,vw.BillID,[ActionDate]) ActionDates    
  OUTER APPLY dbo.IsNotSenateActivityTableValue(ActivityCode,vw.BillID,[ActivityDescription]) as ActivityDescriptions
4

3 に答える 3

3

少なくとも 1 つの行が存在するかどうかを確認するためだけにカウントを取得すると、非常にコストがかかります。代わりに使用する必要がありますEXISTS。これは、カウント全体を具体化せずに短絡する可能性があります。

複数ステートメントのテーブル値関数の代わりに、インライン テーブル値関数を使用するより効率的な方法を次に示します。

ALTER FUNCTION dbo.[IsNotSenateActivityTableValue] -- always use schema prefix!
(
    @ActivityCode int,
    @BillId int,
    @TextToDisplay varchar(max)
)
RETURNS TABLE
AS
  RETURN (SELECT result = CASE WHEN EXISTS 
    (SELECT 1 FROM dbo.BillMaster 
     WHERE BillID = @BillID AND Chamber = 'H'
  ) THEN @TextToDisplay ELSE CASE WHEN EXISTS 
    (SELECT 1 FROM [HouseCoreData].[dbo].[ActivityCode]
      where ActivityDescription not like '%(H)%' 
      and ActivityType = 'S'
      and [ActivityCode] = @ActivityCode
  ) THEN 'test2' ELSE 'test' END
  END);
GO

もちろん、スカラー UDF の場合もあります...

ALTER FUNCTION dbo.[IsNotSenateActivityScalar] -- always use schema prefix!
(
    @ActivityCode int,
    @BillId int,
    @TextToDisplay varchar(max)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
  DECLARE @result VARCHAR(MAX);

  SELECT @result = CASE WHEN EXISTS 
    (SELECT 1 FROM dbo.BillMaster 
     WHERE BillID = @BillID AND Chamber = 'H'
  ) THEN @TextToDisplay ELSE CASE WHEN EXISTS 
    (SELECT 1 FROM [HouseCoreData].[dbo].[ActivityCode]
      where ActivityDescription not like '%(H)%' 
      and ActivityType = 'S'
      and [ActivityCode] = @ActivityCode
  ) THEN 'test2' ELSE 'test' END
  END;

  RETURN (@result);
END
GO
于 2013-10-11T15:01:27.997 に答える
0

テーブル値関数は、他のテーブルと同様に、行を挿入する必要があるテーブルを返します。

の代わりに、次のset @result = .....ようにします。

INSERT INTO @T (result) VALUES ( ..... )

編集:補足として、この関数がテーブル値である理由がよくわかりません。基本的に1つの値を返しています。

于 2013-10-11T14:55:25.123 に答える