如何在表值函数中使用条件联合ALL?

时间:2012-05-21 12:31:30

标签: sql sql-server-2008

以下是内联表值函数

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
)
   )

我定义了两个CTE,DirectPatientChartCTERemotePatientChartCTE。如果RemotePatientChartCTE返回0记录,我不想使用union all。

据我所知,我可以在union all下面的查询中使用where子句来检查CTE中的0条记录。在这种情况下,还将评估第二个查询。我不希望在不存在记录的情况下扫描第二个查询中的表。

由于视角的表现非常糟糕,因此已经从内联TVF改变了。我不能使用SP,因为我必须使用此TVF的结果填充动态临时表。请建议。

1 个答案:

答案 0 :(得分:2)

您可以将函数转换为多语句表值函数。一次执行CTE中的查询,并将每个查询的结果存储在表变量中。然后,您可以检查第二个表变量中的行计数,并在必要时执行联合查询。

在伪代码中就是这样的。

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