如何在SQL Server函数中指定列名?

时间:2018-07-05 03:38:06

标签: sql sql-server

问题是我有一个特定购买订单的多个寄存器,因为每个寄存器都属于同一购买中的不同产品,首先我要执行以下功能:

CREATE FUNCTION TOTALORDEN (@id_orden INT)
RETURNS float
AS
BEGIN
    DECLARE @total FLOAT

    SELECT @total = UnitPrice * Quantity - UnitPrice * Quantity * Discount 
    FROM [Order Details] 
    WHERE @id_orden = OrderID

    RETURN @total
END

但是该函数的问题是仅打印最后一个寄存器的结果。

然后我决定在select指令上使用SQL算术,函数是这样的:

CREATE FUNCTION TOTALORDEN (@id_orden INT)
RETURNS table

    RETURN (SELECT (UnitPrice * Quantity) -
                   (UnitPrice * Quantity * Discount) 
            FROM [Order Details] 
            WHERE @id_orden = OrderID)

它显示的错误是:

  

第3行,TOTALORDEN程序,第16级,状态1,消息4514
  CREATE FUNCTION产生错误,因为没有为第1列指定列名。

表中的部分数据:

enter image description here

3 个答案:

答案 0 :(得分:1)

我猜你错过了聚合函数SUM()

DECLARE @total float

SELECT @total= SUM (UnitPrice*Quantity-UnitPrice*Quantity*Discount) 
FROM [Order Details] 
WHERE @id_orden=OrderID

RETURN @total

答案 1 :(得分:1)

如果您不告诉SQL

SQL不喜欢它,则返回的列是命名的。我使用了FinalPrice的列名,您可以将其更改为您想要的名称。此外,如果您打算使用此功能更新表等,则在表中返回orderid会很有帮助。这应该可以工作:

CREATE FUNCTION [TOTALORDEN] ( @id_orden INT )
RETURNS TABLE
RETURN
(
SELECT OrderId, SUM(( [UnitPrice] * [Quantity] ) - ( [UnitPrice] * [Quantity] * [Discount]) ) AS FinalPrice
FROM
    [Order Details]
WHERE [OrderID] = @id_orden
Group BY OrderId
)

此外,如果您只需要返回总订单金额,那么使用表值函数是一个过大的选择。您应该使用

CREATE FUNCTION [TOTALORDEN] ( @id_orden INT )
RETURNS FLOAT
AS
BEGIN
DECLARE @total FLOAT

SELECT
    @total = SUM (([UnitPrice] * [Quantity]) - ([UnitPrice] * [Quantity] * [Discount]))
FROM
    [Order Details]
WHERE [OrderID] = @id_orden 

RETURN @total
END

也不建议在表名中使用空格,您也应该考虑对其进行重构

答案 2 :(得分:0)

SQL Server标量函数在SQL Server中表现不佳,应尽量避免使用它们。内联表值函数更好,但是在这种情况下,我希望使用类似以下的视图:

CREATE VIEW OrderDetailsSummary
WITH SCHEMABINDING
AS
    SELECT od.OrderID, SUM (ISNULL(od.Quantity * od.UnitPrice * (1 - CAST(od.Discount AS money)), 0)) as OrderTotal, COUNT_BIG(*) AS OrderLineCount
    FROM 
        dbo.OrderDetails od
    GROUP BY
        od.OrderID

GO

此视图可以被索引,使其闪电般快速:

CREATE UNIQUE CLUSTERED INDEX UX_OrderDetailsSummary
ON OrderDetailsSummary(OrderID)

您现在可以通过一个简单的查询来获取订单总数和订单行数:

SELECT *
FROM OrderDetailsSummary WITH (NOEXPAND)
WHERE OrderID = 10260

这是非常有效的。我只需要2个逻辑读取:

  

(受影响的1行)表'OrderDetailsS​​ummary'。扫描计数0,逻辑   读取2,物理读取0,预读0,lob逻辑读取0,   lob物理读取为0,lob提前读取为0。

这是执行计划:

enter image description here

此外,该视图可以与其他视图和表联接。例如,您可以获取订单信息以及摘要数据:

SELECT O.OrderID, O.CustomerID, O.OrderDate, S.OrderTotal, S.OrderLineCount
FROM
    dbo.Orders O
    LEFT OUTER JOIN dbo.OrderDetailsSummary S WITH (NOEXPAND)
        ON O.OrderID = S.OrderID