2013-11-20 5 views
3

저는 SQL 2k5 sproc을 가지고 있습니다.Sproc에서 UDF를 여러 번 사용하기

몇 가지 변수와 사용자 권한에 따라 가격을 계산하려면 UDF를 참조해야합니다. 나는 원래 이것을 시도,하지만 난 필드를 참조되지 않았기 때문에 그것이 작동하지 않았다 ...

SELECT dbo.f_GetPrice(model,userid,authType) 'YourPrice', name, description 
FROM tblRL_Products 
WHERE 'YourPrice' Between @fromPrice AND @toPrice 
    OR 'YourPrice' IS NULL 

그래서 나는 SQL이 SPROC를 실행하면 이 이

, 그것은 을

SELECT dbo.f_GetPrice(model,userid,authType) 'YourPrice', name, description 
FROM tblRL_Products 
WHERE dbo.f_GetPrice(model,userid,authType) Between @fromPrice AND @toPrice 
    OR dbo.f_GetPrice(model,userid,authType) IS NULL 
실행

이 수정 함수 3X는 각 레코드에 대해 또는 한 번 실행하고 한 행당 다른 두 위치의 값을 사용합니다.

더 효율적인 방법이 있습니까?


편집

이 스칼라 UDF이다. 사용자가 승인 한 유형을 기준으로 가격을 책정해야합니다. 그런 다음 올바른 가격을 정하면 계산을해야합니다. 이것은 모두 권한 테이블에 저장됩니다. 모든 사용자는 각 제품 라인에 대한 권한을가집니다. 따라서 각 라인에 대해 서로 다른 가격 유형과 계산 방식을 사용하여 단일 검색 결과 호출에서 수십 또는 수백 라인을 되 돌릴 수 있습니다.

이전 코드 인 authType을 사용하여 위의 코드에서 더 이상 해당 매개 변수를 사용하지 않습니다. 이에 대한 UDF를 사용해야하는 경우

ALTER function [dbo].[f_GetPrice] 
(
    @model uniqueidentifier, 
    @userID uniqueidentifier  
) 
returns money 
as 
begin 

Declare @yourPrice money 

WITH ProductPrice AS(
SELECT (CASE PriceType 
     WHEN 'msrp' THEN p.price_msrp 
      WHEN 'jobber' THEN p.price_jobber 
      WHEN 'warehouse' THEN p.price_warehouse 
      WHEN 'margin' THEN p.price_margin 
      WHEN 'mycost' THEN p.price_mycost 
      WHEN 'customprice1' THEN p.price_custom1 
      WHEN 'customprice2' THEN p.price_custom2 
      WHEN 'customprice3' THEN p.price_custom2 
      ELSE p.price_msrp 
     END) as YourPrice, aup.calc, aup.amount 
FROM products p 
    JOIN lines l ON l.lineID=l.lineID 
    JOIN authorizations a ON l.authlineID=a.authlineID 
    JOIN authorizationusers au ON a.auID=au.auID 
    JOIN authorizationuserprices aup ON au.aupID=aup.aupID 
WHERE [email protected] AND [email protected]) 


SELECT @yourPrice=(CASE calc 
      WHEN 'amount' THEN YourPrice+amount 
      WHEN 'percent' THEN YourPrice+(YourPrice*amount/100) 
      WHEN 'divide' THEN YourPrice/amount 
      WHEN 'factore' THEN YourPrice*amount 
      WHEN 'none' THEN YourPrice 
      ELSE YourPrice 
      END) FROM ProductPrice 

return @yourPrice 

END 
+3

는 dbo.f_GetPrice''의 코드를 보여 주시기 바랍니다 그리고 우리는 *** 좋은 – swasheck

답변

5

는 다음 하위 쿼리 외부 하위 쿼리 및 필터를 사용

select YourPrice, name, description 
from 
(
    SELECT dbo.f_GetPrice(model,userid,authType) YourPrice, name, description 
    FROM tblRL_Products 
) d 
WHERE YourPrice Between @fromPrice AND @toPrice 
    OR YourPrice IS NULL 

그런 다음 당신은 당신의 UDF 번 대신 3 번을 요구하고있다.

+0

정말 *** 당신이 그것을 만들 수 있습니다 복잡한 sproc을 단순화하여 여분의 물건없이 문제를 보여줍니다. 이미 페이징을 수행하기 위해 하위 쿼리에서 이것을 사용하고 있습니다. 나는이 일을 생각했지만 내 두려움은 많은 경우에 내가 실제로 돌아올 때 많은 레코드를 가져올 것이라는 것이었다. 그래서 나는 나중에 다른 critiera에 맞는 모든 레코드를 가져 와서 하위 쿼리 외부에 필요한 수십개의 레코드로 묶었습니다. 그것은 정면을 걸러내는 것보다 오래 걸리는 것처럼 보였다. 그래서 내가 그렇게하지 않았어. –

0

꽤 많은 수의 행에 스칼라 함수를 적용해야하는 경우 스칼라 함수가 좋지 않습니다. 이 경우 확실히 스칼라 함수를 테이블 값 함수로 변환 할 수 있습니다.이 함수는 입력 데이터의 모든 행에 대해 한 번 호출되지 않습니다. 로 다음 사용할 수 있습니다

create function [dbo].[ft_GetPrice] 
(
    @model uniqueidentifier, 
    @userID uniqueidentifier  
) 
returns table 
as return 
(
    WITH ProductPrice AS (
     SELECT (CASE PriceType 
       WHEN 'msrp' THEN p.price_msrp 
        WHEN 'jobber' THEN p.price_jobber 
        WHEN 'warehouse' THEN p.price_warehouse 
        WHEN 'margin' THEN p.price_margin 
        WHEN 'mycost' THEN p.price_mycost 
        WHEN 'customprice1' THEN p.price_custom1 
        WHEN 'customprice2' THEN p.price_custom2 
        WHEN 'customprice3' THEN p.price_custom2 
        ELSE p.price_msrp 
       END) as YourPrice, aup.calc, aup.amount 
     FROM products p 
      JOIN lines l ON l.lineID=l.lineID 
      JOIN authorizations a ON l.authlineID=a.authlineID 
      JOIN authorizationusers au ON a.auID=au.auID 
      JOIN authorizationuserprices aup ON au.aupID=aup.aupID 
     WHERE [email protected] AND [email protected] 
    ) 
    SELECT 
     CASE calc 
      WHEN 'amount' THEN YourPrice+amount 
      WHEN 'percent' THEN YourPrice+(YourPrice*amount/100) 
      WHEN 'divide' THEN YourPrice/amount 
      WHEN 'factore' THEN YourPrice*amount 
      WHEN 'none' THEN YourPrice 
      ELSE YourPrice 
     END as YourPrice 
    FROM ProductPrice 
) 
GO 

: 더 나은 아직

SELECT fp.YourPrice, name, description 
FROM tblRL_Products 
    outer apply dbo.ft_GetPrice(model, userid, authType) fp 
WHERE fp.YourPrice Between @fromPrice AND @toPrice OR fp.YourPrice IS NULL 
+0

나는 이것을 지금 시험 할 것이다. 따라서 테이블 값 함수를 만드는 것이 스칼라보다 빠릅니다. 그것은 여전히 ​​모든 행에 대해 실행되어야합니다. 각 행에 대해 거의 같은 일을 할 때 테이블 값과 반대로 큰 반환 세트에서 스칼라를 훨씬 더 악화시키는 것은 무엇입니까? 확실히 이것을 시도하지만 스칼라 UDF에 대한 명백한 오해에 대해 궁금해합니다. –

+0

@IshmaelStruan, 예, 테이블 함수는 입력 데이터의 모든 행에 대해 계산을 수행하지만, 스칼라 함수 인라인과 달리 테이블 값 함수는 모든 입력 행에 대해 한 번에 연산을 수행합니다. 'select ... '쿼리를 실행 한 것처럼tblRL_Products에서 제품을 조인 ... 인증 사용자 참여 ... 등. 스칼라 함수의 경우 호출이 발생해야하고 결과가 계산되어야하고 호출에서 반환되어야합니다. 1msec의 작은 오버 헤드조차 행을 호출/리턴하는 데 10 초가 걸릴 수 있습니다. 상대적으로 작은 10k 행 세트의 오버 헤드. –

관련 문제