2

目前我有一个udf返回一个table. 它返回3行。每行返回parameter's value *10

像(伪)这样的东西:

ALTER FUNCTION [dbo].[myUdf]
(   
    @num int
)
RETURNS  @myTable TABLE (h int )     

AS
begin
    insert into @myTable 
    SELECT h=@num * 10 UNION
    SELECT h=@num * 20 UNION
    SELECT h=@num * 30
    return @myTable
end

好的。

现在,在我的代码中,我执行以下操作:

select  .... , 
has20 = CASE WHEN EXISTS (SELECT 1 FROM  dbo.myUdf(A.ID) WHERE h=20) 
             THEN 0 ELSE 1 end
,
has30 = CASE WHEN EXISTS (SELECT 1 FROM  dbo.myUdf(A.ID) WHERE h=30)
             THEN 0 ELSE 1 end
...
from A join B...on ...
Where x .. or ..y ... or Exists (select 1 from dbo.myUdf(A.ID) )

请注意多种用法:

在此处输入图像描述

好的。所以我被告知要使用 Cross apply ,所以我这样做了:

所以让我们举一个真正简单的例子:

我有这 3 行数据:

DECLARE @t TABLE(myNum INT)
INSERT @t
VALUES  (1), (2), (3)

所以让我们使用交叉应用:

SELECT  has20  = CASE WHEN  EXISTS( SELECT h FROM myCrossApply WHERE mynum=20 ) 
             THEN '1' ELSE '0' END   , 
        has30  = CASE WHEN  EXISTS( SELECT h FROM myCrossApply WHERE mynum=30 ) 
             THEN '1' ELSE '0' END  
FROM   @t tmp
       CROSS APPLY (
         -- notice  ! in reality there is a udf Table here , I jsut made a simple conversion insted so you can test it.
         SELECT h = tmp.myNum * 10 UNION SELECT h = tmp.myNum * 20 UNION SELECT h = tmp.myNum * 30
        ) myCrossApply

但是这里有2个错误我不知道如何解决:

问题 #1

  • 它无法识别子句中的 myCrossApply EXISTS

在此处输入图像描述

我该如何解决这个问题?

问题2

  • 此外,由于交叉应用,行被重复

例如(让我们删除 unknown exists 子句以显示第二个问题):

SELECT  dummy =  tmp.myNum , myCrossApply.h
         /*...*/ 

FROM   @t tmp
       CROSS APPLY (
         SELECT h = tmp.myNum * 10 UNION SELECT h = tmp.myNum * 20 UNION SELECT h = tmp.myNum * 30
        ) myCrossApply

在此处输入图像描述

我该如何解决这个问题?

我只是不希望每次都重新计算 UDF,所以他们建议使用交叉应用。

4

1 回答 1

1

myCrossApply 不是真正的表,它是对数据子集别名的引用。您也不能将 tmp 称为表。

下面是一些应该使用与您的脚本相同的逻辑的代码:

declare @t table(mynum int)
insert @t values(1),(2),(3)

SELECT  has20  = myCrossApply.chk1, 
        has30  = myCrossApply.chk2,
        mynum
FROM   @t tmp
CROSS APPLY (
SELECT 
  max(case when h = 20 then 1 else 0 end) chk1, 
  max(case when h = 30 then 1 else 0 end) chk2
FROM
(   SELECT h = tmp.myNum * 10
    UNION all
    SELECT h = tmp.myNum * 20 
    UNION all
    SELECT h = tmp.myNum * 30) x
) myCrossApply

结果:

has20   has30   mynum
1       1       1
1       0       2
0       1       3
于 2015-02-25T09:26:38.080 回答