我正在使用SQL 2k5 sproc。
我需要引用UDF来根据一些变量和用户权限来计算价格。我最初尝试过这个,但它没有用,因为我没有引用一个字段......
SELECT dbo.f_GetPrice(model,userid,authType) 'YourPrice', name, description
FROM tblRL_Products
WHERE 'YourPrice' Between @fromPrice AND @toPrice
OR 'YourPrice' IS NULL
所以我将其修改为
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
当SQL执行此sproc时,它是为每条记录运行3X的函数还是一次运行它并使用每行其他两个位置的值。
有更有效的方法吗?
修改
这是Scalar UDF。它需要根据用户授权的类型获取价格,然后一旦我们有合适的价格,我们就需要对其进行计算。这全部存储在授权表中。每个用户都拥有每个产品系列的授权。因此,他们可能为每一行提供不同的价格类型和计算,在一次搜索结果调用中返回数十行甚至数百行。
在上面的代码中,我使用了authType,这是一个旧的调用,我们不再使用该参数了。
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 au.userID=@userID AND p.modelID=@model)
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
答案 0 :(得分:5)
如果必须使用udf,则使用子查询并在子查询外部进行过滤:
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次。
答案 1 :(得分: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 au.userID=@userID AND p.modelID=@model
)
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