SQL Server:使用IF和ELSE返回表的函数

时间:2016-07-07 00:28:21

标签: sql-server

我是SQL Server的新手,所以请耐心等待。我想要做的就是创建一个函数,如果满足某个条件,则返回一个表,条件是折扣金额大于零。如果折扣金额不大于零,则应返回另一个表。我不断收到以下错误:

  

关键字'IF'附近的语法不正确,“和”带有返回值的RETURN语句不能在此上下文中使用。

任何帮助将不胜感激。到目前为止,这是我的代码:

IF OBJECT_ID(N'dbo.fn_PopulateDiscountTable', N'FN') IS NOT NULL
    DROP FUNCTION dbo.fn_PopulateDiscountTable;
GO

CREATE FUNCTION dbo.fn_PopulateDiscountTable(@FolioID smallint)
RETURNS TABLE
AS
    IF((SELECT D.DiscountAmount 
        FROM Discount D, Folio F 
        WHERE D.DiscountID = F.DiscountID 
          AND FolioID = @FolioID) > 0)
        RETURN (SELECT F.QuotedRate AS "QuotedRate", D.DiscountAmount AS "DiscountAmount"
                FROM Discount D, Folio F
                WHERE D.DiscountID = F.DiscountID
                  AND FolioID = @FolioID)
    ELSE
        RETURN(SELECT F.QuotedRate AS "QuotedRate", D.DiscountPercent AS "DiscountPercent"
               FROM Discount D, Folio F
               WHERE D.DiscountID = F.DiscountID
                 AND FolioID = @FolioID)

3 个答案:

答案 0 :(得分:2)

您可以定义要返回的表格并插入其中:

CREATE FUNCTION dbo.fn_PopulateDiscountTable(@FolioID smallint)
RETURNS @Result TABLE
(
     QuotedRate varchar(20), DiscountAmount int
)
AS
BEGIN
IF((SELECT D.DiscountAmount FROM Discount D, Folio F WHERE D.DiscountID = F.DiscountID AND FolioID = @FolioID) > 0)
Insert into @Result
SELECT F.QuotedRate AS "QuotedRate", D.DiscountAmount AS "DiscountAmount"
FROM Discount D, Folio F
WHERE D.DiscountID = F.DiscountID
AND FolioID = @FolioID

ELSE
Insert into @Result 
SELECT F.QuotedRate AS "QuotedRate", D.DiscountPercent AS "DiscountPercent"
FROM Discount D, Folio F
WHERE D.DiscountID = F.DiscountID
AND FolioID = @FolioID

Return --will return @Result
END

答案 1 :(得分:2)

您不能在表值函数中包含分支逻辑,因为从编译器的角度来看,这会导致结果模式的不确定性。

例如,您可能决定从一个分支返回一列字符串,从另一个分支返回十二列xml。表值函数必须具有明确的模式才能被视为表。您遇到的规则是编译器用来保证您的函数用户可以依赖每次返回的相同结果列。

但是,在这种情况下,您可以将逻辑移动到SELECT中的CASE语句,如下所示。

注意:我也冒昧地将连接更新为更现代的ANSI 92 syntax

IF OBJECT_ID(N'dbo.fn_PopulateDiscountTable', N'FN') IS NOT NULL
DROP FUNCTION dbo.fn_PopulateDiscountTable;

GO

CREATE FUNCTION dbo.fn_PopulateDiscountTable(@FolioID smallint)
RETURNS TABLE
AS
RETURN(
  SELECT
    F.QuotedRate AS "QuotedRate"
   ,case when 0 < (
      SELECT D.DiscountAmount
      FROM
        Discount D
        inner join Folio F on f.discountid = d.discountid
      WHERE FolioID = @FolioID
      )
         then D.DiscountAmount
         else d.DiscountPercent
    end AS "Discount"
  FROM
    Discount D
    inner join Folio F on d.discountid = f.discountid
  WHERE f.FolioID = @FolioID
  )

答案 2 :(得分:0)

实际上简单CASE可以完成所有工作:

SELECT
  F.QuotedRate AS "QuotedRate", 
  CASE WHEN D.DiscountAmount > 0 THEN D.DiscountAmount ELSE D.DiscountPercend END AS "Discount"
FROM Discount D
INNER JOIN Folio F ON D.DiscountID = F.DiscountID
WHERE F.FolioID = @FolioID

但请注意,这样的结果没有意义:金额百分比不一样。在大多数情况下,不可能将它们替换为另一个。

0.51.2530.00 - 哪一个是什么?金额或百分比?