2015-02-25 2 views
2

В настоящее время у меня есть udf, который возвращает table. он возвращает 3 строк. Каждая строка возвращает parameter's value *10Cross apply scope не отображается?

Что-то вроде (псевдо):

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

AS 
begin 
    insert into @myTable 
    SELECT [email protected] * 10 UNION 
    SELECT [email protected] * 20 UNION 
    SELECT [email protected] * 30 
    return @myTable 
end 

Ok.

Теперь в моем коде я сделать что-то вроде:

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

Пожалуйста, обратите внимание многоразового использования:

enter image description here

Ok. Так мне сказали, чтобы использовать Cross применить и поэтому я сделал:

Итак, давайте реальный простой пример:

У меня есть эти 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:

enter image description here

Как я могу решить эту проблему?

Вопрос № 2

  • Кроме того, строки mutipled becuase креста применять

Например (давайте удалим неизвестное существует положение, чтобы показать вторую проблему):

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 

enter image description here

Как я могу это решить?

Я просто не хочу, чтобы UDF пересчитывался каждый раз, поэтому они предложили использовать крест.

ответ

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 
+0

Я ожидал, 3 линии: http://i.imgur.com/4Bh3ePU .png –

+0

@RoyiNamir кажется ок, это неправильно? –

+0

есть 3 строки данных. для каждой строки он должен запустить проверку, если has20, имеет 30. si это все еще 3 строки. (разница только как добавленные столбцы) –