选择中的MySQL程序?

时间:2011-12-14 06:00:19

标签: mysql sql stored-procedures user-defined-functions

我有一个这样的程序:

mysql> call Ticket_FiscalTotals(100307);
+---------+--------+----------+------------+------------+
| Service | Items  | SalesTax | eTaxAmount | GrandTotal |
+---------+--------+----------+------------+------------+
| 75.00   | 325.00 | 25.19    | 8.00       | 433.19     |
+---------+--------+----------+------------+------------+
1 row in set (0.08 sec)

我想在select中调用此过程,如下所示:

SELECT     Ticket.TicketID as `Ticket`, 
Ticket.DtCheckOut as `Checkout Date / Time`,
CONCAT(Customer.FirstName, ' ', Customer.LastName) as `Full Name`, 
Customer.PrimaryPhone as `Phone`,

(CALL Ticket_FiscalTotals(Ticket.TicketID)).Service as `Service`

FROM Ticket
INNER JOIN Customer ON Ticket.CustomerID = Customer.CustomerID 
ORDER BY Ticket.SiteHomeLocation, Ticket.TicketID

但我知道这是非常错误的。有人可以指点我正确的方向吗?我需要在最终的Select中访问程序中的所有列(加入?)。该过程中的SQL代码相当痛苦,因此首先是它的原因!

2 个答案:

答案 0 :(得分:8)

Ticket_FiscalTotals过程返回包含某些字段的数据集,但您只需要其中一个 - Service。将您的程序重写为存储的函数 - Get_Ticket_FiscalTotals_Service

另一种方法是在过程中创建和填充临时表,并将此临时表添加到查询中,例如:

DELIMITER $$

CREATE PROCEDURE Ticket_FiscalTotals()
BEGIN
  DROP TEMPORARY TABLE IF EXISTS temp1;
  CREATE TEMPORARY TABLE temp1(
    Service FLOAT(10.2),
    Items FLOAT(10.2),
    SalesTax FLOAT(10.2),
    eTaxAmount FLOAT(10.2),
    GrandTotal FLOAT(10.2)
  );
  INSERT INTO temp1 VALUES (75.0, 325.0, 25.19, 8.0, 433.19);
END
$$

DELIMITER ;

-- Usage
CALL Ticket_FiscalTotals();
SELECT t.*, tmp.service FROM Ticket t, temp1 tmp;

答案 1 :(得分:7)

您无法直接加入存储过程。您可以加入此存储过程填充的临时表:

  1. 创建临时表,
  2. 执行填充临时表中数据的SP,
  3. 在查询中加入临时表,
  4. drop temp table。
  5. 当然,这不是一线解决方案。

    另一种方式(在我看来更糟)我想到的是在SP结果集中拥有尽可能多的UDF列,这可能看起来像是在拖延代码:

    SELECT
        Ticket.TicketID as `Ticket`, 
        Ticket.DtCheckOut as `Checkout Date / Time`,
        CONCAT(Customer.FirstName, ' ', Customer.LastName) as `Full Name`, 
        Customer.PrimaryPhone as `Phone`,
    
        Ticket_FiscalTotals_Service(Ticket.TicketID) as `Service`,
        Ticket_FiscalTotals_Items(Ticket.TicketID) as `Items`,
        Ticket_FiscalTotals_SalesTax(Ticket.TicketID) as `SalesTax`,
        Ticket_FiscalTotals_eTaxAmount(Ticket.TicketID) as `eTaxAmount`,
        Ticket_FiscalTotals_GrandTotal(Ticket.TicketID) as `GrandTotal`
    
    FROM Ticket
    INNER JOIN Customer ON Ticket.CustomerID = Customer.CustomerID 
    ORDER BY Ticket.SiteHomeLocation, Ticket.TicketID