SQL新手,经验丰富的VBA-er需要一些帮助。
我有一个关于需要获得特定类型的不同费用的交易的视图。费用在表中,其中一些字段是必需的,而其他字段可能是NULL。通过这种方式,我们可以设置一般的费用结构,并且仍然允许特定的特价。
我现在的目标是找到最合适的费用。这是费用:
NULL
,现在我得到了这个代码的一个版本,但作为一个程序。但是因为我需要在视图中使用它,所以我不能使用该版本,并且函数中不允许使用临时表。
在查看此论坛和其他人之后,我得出的结果仍然是2个错误:
1. ErrorMessage:'@tblTEMP'
附近的语法不正确,
2. ErrorMessage:'BEGIN'
附近的语法不正确。
我当前的脚本如下(使用局部变量表):
ALTER FUNCTION [dbo].[fnStandardFeeBAK]
(@Type_Id BIGINT, @Party_Id BIGINT, @I_A_Id BIGINT, @Grid_Id BIGINT,
@Market_Id BIGINT, @Counterparty_Id BIGINT, @Product_Id BIGINT,
@DealDate DATETIME)
RETURNS TABLE
AS
BEGIN
DECLARE @tblTEMP TABLE (Standard_Fee DECIMAL(38,8), Currency VARCHAR(50),
Unit VARCHAR(50), Unit2 VARCHAR(50), MatchScore BIGINT);
WITH @tblTEMP AS
(SELECT Standard_Fee, V2.Element AS Currency, V1.Element AS Unit,
V2.Element+'/'+V1.Element AS Unit2,
SF.I_A_Id, SF.Grid_Id, SF.Product_Id, SF.Counterparty_Id,
(CASE WHEN SF.I_A_Id = @I_A_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Grid_Id = @Grid_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Product_Id = @Product_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Counterparty_Id = @Counterparty_Id THEN 1 ELSE 0 END)
AS MatchScore
FROM tblStandard_Fee AS SF
LEFT JOIN tblElement AS V1 ON V1.Element_Id = SF.Unit_Id
LEFT JOIN tblElement AS V2 ON V2.Element_Id = SF.Currency_Id
WHERE SF.Type_Id = @Type_Id AND SF.Party_Id = @Party_Id AND
SF.Market_Id = @Market_Id
AND SF.Date_From < @DealDate
AND (SF.Date_To > @DealDate OR SF.Date_To IS NULL)
AND (SF.I_A_Id = @I_A_Id OR SF.I_A_Id IS NULL)
AND (SF.Grid_Id = @Grid_Id OR SF.Grid_Id IS NULL)
AND (SF.Product_Id = @Product_Id OR SF.Product_Id IS NULL)
AND (SF.Counterparty_Id = @Counterparty_Id OR SF.Counterparty_Id IS NULL))
RETURN
SELECT Standard_Fee, Currency, Unit, Unit2
FROM @tblTEMP
WHERE MatchScore= MAX(MatchScore)
END
如果不让我知道,我希望我的问题很清楚。
感谢您提出建议,甚至用最后一点解决我的问题!
因此所有LittleBobbyTables的帮助结合起来给了我一个有效的结果。请不要忘记给他这个信用。
工作代码:
ALTER FUNCTION [dbo].[fnStandardFeeBAK]
(@Type_Id BIGINT, @Party_Id BIGINT, @I_A_Id BIGINT, @Grid_Id BIGINT,
@Market_Id BIGINT, @Counterparty_Id BIGINT, @Product_Id BIGINT, @DealDate DATETIME)
RETURNS @YourTable TABLE
(
-- Columns returned by the function
Standard_Fee DECIMAL(38,8),
Currency VARCHAR(50),
Unit VARCHAR(50),
Unit2 VARCHAR(50)
)
AS
BEGIN
WITH YourCTE(Standard_Fee, Currency, Unit, Unit2, MatchScore) AS
(
SELECT Standard_Fee, V2.Element AS Currency, V1.Element AS Unit,
V2.Element + '/' + V1.Element AS Unit2,
(CASE WHEN SF.I_A_Id = @I_A_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Grid_Id = @Grid_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Product_Id = @Product_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Counterparty_Id = @Counterparty_Id THEN 1 ELSE 0 END)
AS MatchScore
FROM tblStandard_Fee AS SF
LEFT JOIN tblElement AS V1 ON V1.Element_Id = SF.Unit_Id
LEFT JOIN tblElement AS V2 ON V2.Element_Id = SF.Currency_Id
--Type_ID, Party_ID and Market_Id are always present, others can have NULL values
WHERE SF.Type_Id = @Type_Id AND SF.Party_Id = @Party_Id
AND SF.Market_Id = @Market_Id AND SF.Date_From < @DealDate
AND (SF.Date_To > @DealDate OR SF.Date_To IS NULL)
AND (SF.I_A_Id = @I_A_Id OR SF.I_A_Id IS NULL)
AND (SF.Grid_Id = @Grid_Id OR SF.Grid_Id IS NULL)
AND (SF.Product_Id = @Product_Id OR SF.Product_Id IS NULL)
AND (SF.Counterparty_Id = @Counterparty_Id OR SF.Counterparty_Id IS NULL)
GROUP BY Standard_Fee, V1.Element, V2.Element, SF.I_A_Id, SF.Grid_Id, SF.Product_Id, SF.Counterparty_Id
)
INSERT @YourTable
SELECT Standard_Fee, Currency, Unit, Unit2
FROM YourCTE
GROUP BY MatchScore, Standard_Fee, Currency, Unit, Unit2
HAVING MatchScore = (SELECT MAX(MatchScore) FROM YourCTE)
RETURN;
END
答案 0 :(得分:2)
请参阅Table-Valued User-Defined Functions文档,正确的语法是:
ALTER FUNCTION dbo.fnStandardFeeBAK(@Type_Id BIGINT, @Party_Id BIGINT,
@I_A_Id BIGINT, @Grid_Id BIGINT, @Market_Id BIGINT,
@Counterparty_Id BIGINT, @Product_Id BIGINT,
@DealDate DATETIME)
RETURNS @YourTable TABLE
(
-- Columns returned by the function
Standard_Fee DECIMAL(38,8),
Currency VARCHAR(50),
Unit VARCHAR(50),
Unit2 VARCHAR(50)
)
AS
最后:
INSERT @YourTable
SELECT Standard_Fee, Currency, Unit, Unit2
FROM YourCTE
WHERE MatchScore= MAX(MatchScore)
RETURN;
END;
编辑:搞砸了CTE,你不需要临时表。
把它们放在一起,你得到:
ALTER FUNCTION dbo.fnStandardFeeBAK(@Type_Id BIGINT, @Party_Id BIGINT,
@I_A_Id BIGINT, @Grid_Id BIGINT, @Market_Id BIGINT,
@Counterparty_Id BIGINT, @Product_Id BIGINT,
@DealDate DATETIME)
RETURNS @YourTable TABLE
(
-- Columns returned by the function
Standard_Fee DECIMAL(38,8),
Currency VARCHAR(50),
Unit VARCHAR(50),
Unit2 VARCHAR(50)
)
AS
BEGIN
WITH YourCTE (Standard_Fee, Currency, Unit, Unit2, MatchScore) AS
(SELECT Standard_Fee, V2.Element AS Currency, V1.Element AS Unit,
V2.Element+'/'+V1.Element AS Unit2,
SF.I_A_Id, SF.Grid_Id, SF.Product_Id, SF.Counterparty_Id,
(CASE WHEN SF.I_A_Id = @I_A_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Grid_Id = @Grid_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Product_Id = @Product_Id THEN 1 ELSE 0 END +
CASE WHEN SF.Counterparty_Id = @Counterparty_Id THEN 1 ELSE 0 END)
AS MatchScore
FROM tblStandard_Fee AS SF
LEFT JOIN tblElement AS V1 ON V1.Element_Id = SF.Unit_Id
LEFT JOIN tblElement AS V2 ON V2.Element_Id = SF.Currency_Id
WHERE SF.Type_Id = @Type_Id AND SF.Party_Id = @Party_Id AND
SF.Market_Id = @Market_Id
AND SF.Date_From < @DealDate
AND (SF.Date_To > @DealDate OR SF.Date_To IS NULL)
AND (SF.I_A_Id = @I_A_Id OR SF.I_A_Id IS NULL)
AND (SF.Grid_Id = @Grid_Id OR SF.Grid_Id IS NULL)
AND (SF.Product_Id = @Product_Id OR SF.Product_Id IS NULL)
AND (SF.Counterparty_Id = @Counterparty_Id OR SF.Counterparty_Id IS NULL))
INSERT @YourTable
SELECT Standard_Fee, Currency, Unit, Unit2
FROM YourCTE
WHERE MatchScore= MAX(MatchScore)
RETURN;
END;