I worked on the following code. It uses an XML file. The file or line contains the date ranges to be summarized. The stored procedure will return a table with totals for a specific range.
DECLARE @balance_transactions TABLE(fee FLOAT, source INT, account_id INT, [type] VARCHAR(25), created DATETIME) INSERT INTO @balance_transactions SELECT 12.5, 1, 6, 'charge', '01/15/2012' UNION SELECT 70, 2, 6, 'charge', '01/16/2012' UNION SELECT 136.89, 3, 6, 'charge', '01/17/2012' UNION SELECT 29.16, 4, 6, 'charge', '01/18/2012' UNION SELECT 1369.54, 5, 6, 'charge', '02/21/2012' UNION SELECT 468.85, 6, 6, 'charge', '02/22/2012' UNION SELECT 65.8, 7, 6, 'charge', '02/22/2012' UNION SELECT 1236.87, 8, 6, 'charge', '02/22/2012' DECLARE @charges TABLE(balance_id INT, refunded BIT, invoice INT) INSERT INTO @charges SELECT 1, 0, 7 UNION SELECT 2, 0, 8 UNION SELECT 3, 0, 9 UNION SELECT 4, 0, 10 UNION SELECT 5, 0, 11 UNION SELECT 6, 0, 12 UNION SELECT 7, 0, null UNION SELECT 8, 0, null SET DATEFORMAT MDY DECLARE @XmlDocumentHandle int DECLARE @XmlDocument nvarchar(4000) SET @XmlDocument = N'<dates> <range> <fromDate>01/15/2012</fromDate> <toDate>01/30/2012</toDate> </range> <range> <fromDate>02/15/2012</fromDate> <toDate>02/28/2012</toDate> </range> </dates>' EXEC sp_xml_preparedocument @XmlDocumentHandle OUTPUT, @XmlDocument DECLARE @feeTotal TABLE(fromDate DATETIME, toDate DATETIME, total FLOAT) DECLARE @fromDate DATETIME DECLARE @toDate DATETIME DECLARE ranges_cur CURSOR FOR SELECT fromDate, toDate FROM OPENXML (@XmlDocumentHandle, '/dates/range',2) WITH (fromDate DATETIME, toDate DATETIME); OPEN ranges_cur; FETCH NEXT FROM ranges_cur INTO @fromDate, @toDate; WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO @feeTotal SELECT @fromDate, @toDate, SUM(bt.fee) FROM @balance_transactions bt INNER JOIN @charges c ON bt.source = c.balance_id WHERE bt.account_id = 6 AND (bt.type = 'charge' AND c.refunded = 0 AND c.invoice IS NOT NULL) AND (bt.created >= @fromDate AND bt.created <= @toDate); FETCH NEXT FROM ranges_cur INTO @fromDate, @toDate; END; CLOSE ranges_cur; DEALLOCATE ranges_cur; SELECT fromDate, toDate, total FROM @feeTotal EXEC sp_xml_removedocument @XmlDocumentHandle GO
A parameterized query will look like this.
CREATE PROCEDURE spGetTotalsPerDateRange(@XmlDocument NVARCHAR(4000), @type VARCHAR(50) = 'charge', @refunded BIT = 0) AS BEGIN SET DATEFORMAT MDY DECLARE @XmlDocumentHandle INT EXEC sp_xml_preparedocument @XmlDocumentHandle OUTPUT, @XmlDocument DECLARE @feeTotal TABLE(fromDate DATETIME, toDate DATETIME, total FLOAT) DECLARE @fromDate DATETIME DECLARE @toDate DATETIME DECLARE ranges_cur CURSOR FOR SELECT fromDate, toDate FROM OPENXML (@XmlDocumentHandle, '/dates/range',2) WITH (fromDate DATETIME, toDate DATETIME); OPEN ranges_cur; FETCH NEXT FROM ranges_cur INTO @fromDate, @toDate; WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO @feeTotal SELECT @fromDate, @toDate, SUM(bt.fee) FROM balance_transactions bt INNER JOIN charges c ON bt.source = c.balance_id WHERE bt.account_id = 6 AND (bt.type = 'charge' AND c.refunded = 0 AND c.invoice IS NOT NULL) AND (bt.created >= @fromDate AND bt.created <= @toDate); FETCH NEXT FROM ranges_cur INTO @fromDate, @toDate; END; CLOSE ranges_cur; DEALLOCATE ranges_cur; SELECT fromDate, toDate, total FROM @feeTotal EXEC sp_xml_removedocument @XmlDocumentHandle END GO
The first code was tested using fake data and it works correctly. You need to make the necessary changes to the types and names in the SP columns and variable types according to the definition of your tables.
The idea behind this approach is to communicate any information as you need. You can also pass additional parameters through XML attributes. Learn more about OPEN XML at MSDN
Hope this helps