1

以下はインラインテーブル値関数です

CREATE FUNCTION [dbo].[GetDipForDirectClientCharts]
(
  @FacilityId AS UNIQUEIDENTIFIER ,
  @PatientChartStatusCompleteEnum SMALLINT ,
  @PatientChartLockingInterval SMALLINT
)
RETURNS TABLE
AS RETURN
(            
    WITH    DirectPatientChartCTE
              --Get all patient charts that qualify for dip criteria   
              AS ( SELECT TOP 500
                            VisitNumber,PatientChartID
                   FROM     PatientChartCorporate WITH ( READPAST )
                   WHERE    PatientChartCorporate.IsDeleted = 0
                            AND PatientChartCorporate.IsErroneous = 0
                            AND PatientChartCorporate.FacilityId = @FacilityId
                            AND ( DipFileName IS NULL
                                  OR DipFileName = ''
                                )
                            AND PatientChartCorporate.ChartStatusID = @PatientChartStatusCompleteEnum
                            AND DATEDIFF(MINUTE, CompletedOn, GETUTCDATE()) >= +CONVERT(VARCHAR(30), @PatientChartLockingInterval)
                            AND ( PatientChartCorporate.CompletedOn IS NOT NULL )
                 ),
            RemotePatientChartCTE
              AS ( SELECT TOP 500
                            VisitNumber,PatientChartID
                   FROM     PatientCharts WITH ( READPAST )
                   WHERE    PatientCharts.IsDeleted = 0
                            AND PatientCharts.IsErroneous = 0
                            AND PatientCharts.FacilityId = @FacilityId
                            AND ( DipFileName IS NULL
                                  OR DipFileName = ''
                                )
                            AND PatientCharts.ChartStatusID = @PatientChartStatusCompleteEnum
                            AND DATEDIFF(MINUTE, CompletedOn, GETUTCDATE()) >= +CONVERT(VARCHAR(30), @PatientChartLockingInterval)
                            AND ( PatientCharts.CompletedOn IS NOT NULL )
                 )
SELECT  PatientCharts.VisitNumber ,
        PatientChartImages.ImageSequence AS ImageSequence
FROM    dbo.PatientChartImagesCorporate AS PatientChartImages WITH ( READPAST )
        INNER JOIN DirectPatientChartCTE AS PatientCharts ON PatientChartImages.PatientChartId = PatientCharts.PatientChartId
WHERE   Patientchartimages.OnbasedDate IS NULL
UNION ALL
( SELECT    PatientCharts.VisitNumber ,
            PatientChartImages.ImageSequence AS ImageSequence
  FROM      dbo.PatientChartImages AS PatientChartImages WITH ( READPAST )
            INNER JOIN RemotePatientChartCTE AS PatientCharts ON PatientChartImages.PatientChartId = PatientCharts.PatientChartId
  WHERE     Patientchartimages.OnbasedDate IS NULL
)
   )

2 つの CTE と を定義DirectPatientChartCTERemotePatientChartCTEました。によって 0 レコードが返される場合に備えて、union all を使用したくありませんRemotePatientChartCTE

CTE の 0 レコードをチェックするために、union all の下のクエリで where 句を使用できることを理解しています。その場合、2 番目のクエリも評価されます。レコードが存在しない場合に備えて、2 番目のクエリのテーブルをスキャンしたくありません。

これは、ビューでのパフォーマンスがひどかったため、ビューからインライン TVF に変更されました。この TVF の結果を動的一時テーブルに入力する必要があるため、SP を使用できません。提案してください。

4

1 に答える 1

2

関数を複数ステートメントのテーブル値関数に変えることができます。CTE のクエリを一度に 1 つずつ実行し、各クエリの結果をそれぞれテーブル変数に格納します。次に、2 番目のテーブル変数の行数を確認し、必要に応じてユニオン クエリを実行できます。

疑似コードでは、このようなものです。

declare @Direct table
(
  PatientChartID int primary key,
  VisitNumber int
)

declare @Remote table
(
  PatientChartID int primary key,
  VisitNumber int
)

insert into @Direct 
select top 500 VisitNumber,PatientChartID
from PatientChartCorporate
--where ....

insert into @Remote
select top 500 VisitNumber,PatientChartID
from PatientChartCorporate
--where ....

if exists(select * from @Remote)
begin
  -- union query here

end
else
begin
  -- non union query here

end
于 2012-05-21T12:40:30.257 に答える