I wrote a function in SQL that returns a table of running numbers and totals. I don't know if it's possible to return a table in oracle or not. I know there are some differences between Oracle and SQL syntax so I started to modify my SQL function and pasted below. I am hoping someone can assist with the syntax.
Basically, I am trying to create a temporary table where I can count and sum. With the SQL Function I was able to call to the Max(TotalDollar) field in a subquery, but my output was a table. As I said, I'm not sure I can use "TABLE" as a return type in Oracle so all I really need is an OUTPUT of Max(TotalDollar) so long as I can call to the Function with the parameters I specified.
Any help is greatly appreciated!!
______________________________________________________
--MY ATTEMPT AT THE ORACLE SYNTAX--
CREATE FUNCTION fnFIFO (site IN varchar2, stock IN varchar2)
RETURNS NUMBER(15,5)
curRunningTotal IS CURSOR
Report IS
( tran_ts DATE,
site_id VARCHAR2,
stock_item_nbr VARCHAR2,
unit_cost NUMBER(15,5),
qty INTEGER,
qty_on_hand INTEGER,
RunningTotal INTEGER,
TotalDollar NUMBER(15,5)
);
curRunningTotal IS CURSOR
basequery IS SELECT IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR,
COALESCE (SUM(IV_TRANSACTIONS.UNIT_COST), 0) unit_cost,
SUM(IV_TRANSACTIONS.QUANTITY - COALESCE (IV_TRANSACTIONS.RECEIPT_QTY_ISSUED, 0)) qty,
COALESCE((SELECT SUM(QTY_ON_HAND) Expr1
FROM STOCK_ITEM_LOCATIONS
WHERE (SITE_ID = site) AND (STOCK_ITEM_NBR = stock)
GROUP BY SITE_ID, STOCK_ITEM_NBR), 0) qty_on_hand
FROM IV_TRANSACTIONS
WHERE IV_TRANSACTIONS.SITE_ID = site and IV_TRANSACTIONS.STOCK_ITEM_NBR = stock
GROUP BY IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR
ORDER BY IV_TRANSACTIONS.TRAN_TS ASC, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR;
tran_ts DATE;
site_id VARCHAR2;
stock_item_nbr VARCHAR2;
unit_cost NUMBER(15,5);
qty INTEGER;
qty_on_hand INTEGER;
RunningTotal INTEGER :=0;
TotalDollar NUMBER(15,5) :=0;
BEGIN OPEN basequery;
FETCH basequery
INTO tran_ts,
site_id,
stock_item_nbr,
unit_cost,
qty,
qty_on_hand;
OPEN curRunningTotal;
FETCH NEXT FROM curRunningTotal;
LOOP EXIT WHEN RunningTotal <= qty_on_hand;
IF RunningTotal >= qty_on_hand
THEN TotalDollar := TotalDollar + ((qty - (RunningTotal - qty_on_hand)) * unit_cost)
ELSE
TotalDollar := TotalDollar + (qty * unit_cost);
INSERT Report
VALUES(tran_ts, site_id, stock_item_nbr, unit_cost, qty, qty_on_hand, RunningTotal, TotalDollar)
FETCH NEXT FROM curRunningTotal
INTO tran_ts,
site_id,
stock_item_nbr,
unit_cost,
qty,
qty_on_hand
END LOOP;
CLOSE curRunningTotal;
RETURN Max(TotalDollar);
END fnFIFO;
_______________________________________________
--HERE IS THE FUNCTIONING SQL SYNTAX--
CREATE FUNCTION fnFIFO
(
@site char(5),
@stock char(10)
)
RETURNS
@Report TABLE
(
tran_ts DATETIME,
site_id CHAR(5),
stock_item_nbr CHAR(20),
unit_cost NUMERIC(15,5),
qty INT,
qty_on_hand INT,
RunningTotal INT,
TotalDollar NUMERIC(15,5)
)
AS
BEGIN
DECLARE curRunningTotal CURSOR LOCAL FAST_FORWARD FOR
SELECT IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR, COALESCE (SUM(IV_TRANSACTIONS.UNIT_COST), 0) AS unit_cost,
SUM(IV_TRANSACTIONS.QUANTITY - COALESCE
(IV_TRANSACTIONS.RECEIPT_QTY_ISSUED, 0)) AS qty,
COALESCE((SELECT SUM(QTY_ON_HAND) AS Expr1
FROM STOCK_ITEM_LOCATIONS
WHERE (SITE_ID = @site) AND
(STOCK_ITEM_NBR = @stock)
GROUP BY SITE_ID, STOCK_ITEM_NBR), 0) AS qty_on_hand
FROM IV_TRANSACTIONS
WHERE IV_TRANSACTIONS.SITE_ID = @site and IV_TRANSACTIONS.STOCK_ITEM_NBR = @stock
GROUP BY IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR
ORDER BY IV_TRANSACTIONS.TRAN_TS ASC, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR
;
OPEN curRunningTotal
DECLARE @tran_ts DATETIME
DECLARE @site_id CHAR(5)
DECLARE @stock_item_nbr CHAR(20)
DECLARE @unit_cost NUMERIC(15,5)
DECLARE @qty INT
DECLARE @qty_on_hand INT
DECLARE @RunningTotal INT
DECLARE @TotalDollar NUMERIC(15,5)
SET @RunningTotal = 0
SET @TotalDollar = 0
FETCH NEXT FROM curRunningTotal
INTO @tran_ts,
@site_id,
@stock_item_nbr,
@unit_cost,
@qty,
@qty_on_hand
WHILE @@FETCH_STATUS = 0 and @RunningTotal <= @qty_on_hand
BEGIN
SET @RunningTotal = @RunningTotal + @qty
IF @RunningTotal >= @qty_on_hand
SET @TotalDollar = @TotalDollar + ((@qty - (@RunningTotal - @qty_on_hand)) * @unit_cost)
ELSE
SET @TotalDollar = @TotalDollar + (@qty * @unit_cost)
INSERT @Report
VALUES(@tran_ts, @site_id, @stock_item_nbr, @unit_cost, @qty, @qty_on_hand, @RunningTotal, @TotalDollar)
FETCH NEXT FROM curRunningTotal
INTO @tran_ts,
@site_id,
@stock_item_nbr,
@unit_cost,
@qty,
@qty_on_hand
END
CLOSE curRunningTotal
DEALLOCATE curRunningTotal
RETURN
;
END
GO
Basically, I am trying to create a temporary table where I can count and sum. With the SQL Function I was able to call to the Max(TotalDollar) field in a subquery, but my output was a table. As I said, I'm not sure I can use "TABLE" as a return type in Oracle so all I really need is an OUTPUT of Max(TotalDollar) so long as I can call to the Function with the parameters I specified.
Any help is greatly appreciated!!
______________________________________________________
--MY ATTEMPT AT THE ORACLE SYNTAX--
CREATE FUNCTION fnFIFO (site IN varchar2, stock IN varchar2)
RETURNS NUMBER(15,5)
curRunningTotal IS CURSOR
Report IS
( tran_ts DATE,
site_id VARCHAR2,
stock_item_nbr VARCHAR2,
unit_cost NUMBER(15,5),
qty INTEGER,
qty_on_hand INTEGER,
RunningTotal INTEGER,
TotalDollar NUMBER(15,5)
);
curRunningTotal IS CURSOR
basequery IS SELECT IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR,
COALESCE (SUM(IV_TRANSACTIONS.UNIT_COST), 0) unit_cost,
SUM(IV_TRANSACTIONS.QUANTITY - COALESCE (IV_TRANSACTIONS.RECEIPT_QTY_ISSUED, 0)) qty,
COALESCE((SELECT SUM(QTY_ON_HAND) Expr1
FROM STOCK_ITEM_LOCATIONS
WHERE (SITE_ID = site) AND (STOCK_ITEM_NBR = stock)
GROUP BY SITE_ID, STOCK_ITEM_NBR), 0) qty_on_hand
FROM IV_TRANSACTIONS
WHERE IV_TRANSACTIONS.SITE_ID = site and IV_TRANSACTIONS.STOCK_ITEM_NBR = stock
GROUP BY IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR
ORDER BY IV_TRANSACTIONS.TRAN_TS ASC, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR;
tran_ts DATE;
site_id VARCHAR2;
stock_item_nbr VARCHAR2;
unit_cost NUMBER(15,5);
qty INTEGER;
qty_on_hand INTEGER;
RunningTotal INTEGER :=0;
TotalDollar NUMBER(15,5) :=0;
BEGIN OPEN basequery;
FETCH basequery
INTO tran_ts,
site_id,
stock_item_nbr,
unit_cost,
qty,
qty_on_hand;
OPEN curRunningTotal;
FETCH NEXT FROM curRunningTotal;
LOOP EXIT WHEN RunningTotal <= qty_on_hand;
IF RunningTotal >= qty_on_hand
THEN TotalDollar := TotalDollar + ((qty - (RunningTotal - qty_on_hand)) * unit_cost)
ELSE
TotalDollar := TotalDollar + (qty * unit_cost);
INSERT Report
VALUES(tran_ts, site_id, stock_item_nbr, unit_cost, qty, qty_on_hand, RunningTotal, TotalDollar)
FETCH NEXT FROM curRunningTotal
INTO tran_ts,
site_id,
stock_item_nbr,
unit_cost,
qty,
qty_on_hand
END LOOP;
CLOSE curRunningTotal;
RETURN Max(TotalDollar);
END fnFIFO;
_______________________________________________
--HERE IS THE FUNCTIONING SQL SYNTAX--
CREATE FUNCTION fnFIFO
(
@site char(5),
@stock char(10)
)
RETURNS
@Report TABLE
(
tran_ts DATETIME,
site_id CHAR(5),
stock_item_nbr CHAR(20),
unit_cost NUMERIC(15,5),
qty INT,
qty_on_hand INT,
RunningTotal INT,
TotalDollar NUMERIC(15,5)
)
AS
BEGIN
DECLARE curRunningTotal CURSOR LOCAL FAST_FORWARD FOR
SELECT IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR, COALESCE (SUM(IV_TRANSACTIONS.UNIT_COST), 0) AS unit_cost,
SUM(IV_TRANSACTIONS.QUANTITY - COALESCE
(IV_TRANSACTIONS.RECEIPT_QTY_ISSUED, 0)) AS qty,
COALESCE((SELECT SUM(QTY_ON_HAND) AS Expr1
FROM STOCK_ITEM_LOCATIONS
WHERE (SITE_ID = @site) AND
(STOCK_ITEM_NBR = @stock)
GROUP BY SITE_ID, STOCK_ITEM_NBR), 0) AS qty_on_hand
FROM IV_TRANSACTIONS
WHERE IV_TRANSACTIONS.SITE_ID = @site and IV_TRANSACTIONS.STOCK_ITEM_NBR = @stock
GROUP BY IV_TRANSACTIONS.TRAN_TS, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR
ORDER BY IV_TRANSACTIONS.TRAN_TS ASC, IV_TRANSACTIONS.SITE_ID, IV_TRANSACTIONS.STOCK_ITEM_NBR
;
OPEN curRunningTotal
DECLARE @tran_ts DATETIME
DECLARE @site_id CHAR(5)
DECLARE @stock_item_nbr CHAR(20)
DECLARE @unit_cost NUMERIC(15,5)
DECLARE @qty INT
DECLARE @qty_on_hand INT
DECLARE @RunningTotal INT
DECLARE @TotalDollar NUMERIC(15,5)
SET @RunningTotal = 0
SET @TotalDollar = 0
FETCH NEXT FROM curRunningTotal
INTO @tran_ts,
@site_id,
@stock_item_nbr,
@unit_cost,
@qty,
@qty_on_hand
WHILE @@FETCH_STATUS = 0 and @RunningTotal <= @qty_on_hand
BEGIN
SET @RunningTotal = @RunningTotal + @qty
IF @RunningTotal >= @qty_on_hand
SET @TotalDollar = @TotalDollar + ((@qty - (@RunningTotal - @qty_on_hand)) * @unit_cost)
ELSE
SET @TotalDollar = @TotalDollar + (@qty * @unit_cost)
INSERT @Report
VALUES(@tran_ts, @site_id, @stock_item_nbr, @unit_cost, @qty, @qty_on_hand, @RunningTotal, @TotalDollar)
FETCH NEXT FROM curRunningTotal
INTO @tran_ts,
@site_id,
@stock_item_nbr,
@unit_cost,
@qty,
@qty_on_hand
END
CLOSE curRunningTotal
DEALLOCATE curRunningTotal
RETURN
;
END
GO