一个存储过程中有多个 SQL 语句。超出范围异常

Multiple SQL statements in one stored procedure. Out of Range exception

我正在使用数据 reader 通过 3 个不同的查询从单个 table 中获取值。我在“billed030”上得到一个“System.IndexOutOfRangeException”,它在下面的第二个 select 语句中。

这里怎么查询数据库,因为每次查询的“where”都不一样。

BEGIN
    SET NOCOUNT ON;

    SELECT SUM(CAST(AmountBilled AS decimal(18, 2))) AS billed,
           SUM(CAST(AmountPaid AS decimal(18, 2))) AS paid
    FROM OrderBilling
         LEFT OUTER JOIN Orders ON OrderBilling.LinkId = Orders.LinkId
                               AND Orders.OwnerId = @OwnerId
    WHERE OrderBilling.PaidInFull = 'False'
      AND OrderBilling.OwnerID = @OwnerID
      AND ClientId = @ClientId
    UNION ALL
    SELECT SUM(CAST(AmountBilled AS decimal(18, 2))) AS billed030,
           SUM(CAST(AmountPaid AS decimal(18, 2))) AS paid030
    FROM OrderBilling
         LEFT OUTER JOIN Orders ON OrderBilling.LinkId = Orders.LinkId
                               AND Orders.OwnerId = @OwnerId
    WHERE OrderBilling.InvoiceDate BETWEEN DATEADD(MONTH, -1, GETDATE()) AND GETDATE()
      AND OrderBilling.PaidInFull = 'False'
      AND OrderBilling.OwnerID = @OwnerID
      AND ClientId = @ClientId
    UNION ALL
    SELECT SUM(CAST(AmountBilled AS decimal(18, 2))) AS billed3060,
           SUM(CAST(AmountPaid AS decimal(18, 2))) AS paid3060
    FROM OrderBilling
         LEFT OUTER JOIN Orders ON OrderBilling.LinkId = Orders.LinkId
                               AND Orders.OwnerId = @OwnerId
    WHERE OrderBilling.InvoiceDate BETWEEN DATEADD(MONTH, -2, GETDATE()) AND DATEADD(MONTH, -1, GETDATE())
      AND OrderBilling.PaidInFull = 'False'
      AND OrderBilling.OwnerID = @OwnerID
      AND ClientId = @ClientId;
END;

这并没有具体回答问题(这不是 SQL 服务器错误),但是,我认为这里不需要 3 UNION ALL 查询。您可以使用一些条件聚合,然后使用一些反透视来接收相同的数据集:

WITH CTE AS(
    SELECT SUM(CAST(O.AmountBilled AS decimal(18, 2))) AS billed, --If AmountBilled is in the table Orders, why a LEFT JOIN? If it isn't, why JOIN at all?
           SUM(CAST(O.AmountPaid AS decimal(18, 2))) AS paid,
           SUM(CASE WHEN OB.InvoiceDate BETWEEN DATEADD(MONTH, -1, GETDATE()) AND GETDATE() THEN CAST(O.AmountBilled AS decimal(18, 2)) END) AS billed030,
           SUM(CASE WHEN OB.InvoiceDate BETWEEN DATEADD(MONTH, -1, GETDATE()) AND GETDATE() THEN CAST(O.AmountPaid AS decimal(18, 2)) END) AS paid030,
           SUM(CASE WHEN OB.InvoiceDate BETWEEN DATEADD(MONTH, -2, GETDATE()) AND DATEADD(MONTH, -1, GETDATE()) THEN CAST(O.AmountBilled AS decimal(18, 2)) END) AS billed3060,
           SUM(CASE WHEN OB.InvoiceDate BETWEEN DATEADD(MONTH, -2, GETDATE()) AND DATEADD(MONTH, -1, GETDATE()) THEN CAST(O.AmountPaid AS decimal(18, 2)) END) AS paid3060
    FROM dbo.OrderBilling OB
         LEFT OUTER JOIN dbo.Orders O ON OB.LinkId = O.LinkId
                                     AND O.OwnerId = @OwnerId
    WHERE OB.PaidInFull = 'False'
      AND OB.OwnerID = @OwnerID
      AND OB.ClientId = @ClientId)
SELECT --V.category,
       V.billed,
       V.paid
FROM CTE C
     CROSS APPLY (VALUES('',C.billed,C.paid),
                        ('030',C.billed030,C.paid3060),
                        ('3060',C.billed3060,C.paid3060))V(category,billed,paid);