Return multiple values from PL/SQL Function

OmniOwl picture OmniOwl · May 3, 2014 · Viewed 65.7k times · Source

I need to try and find a free seat on a plane, and then reserve that seat.

I need to return both a value to indicate success or not as well as a seat number. By looking around I've found that functions can't return more than 1 value so I thought about using an array but looking at documentation for those made it apparent that I am not nearly good enough at PL/SQL to understand how to use them.

So here I am, stranded.

The code that I got so far looks like this:

CREATE OR REPLACE FUNCTION RESERVE_SEAT(P_NO VARCHAR2, ID NUMBER, RESERVE_TIME NUMBER, S_NO VARCHAR2)
RETURN INTEGER AS
  RES INTEGER := 0;
  COUNTS INTEGER := 0;
BEGIN
SELECT COUNT(*) INTO COUNTS FROM SEAT WHERE SEAT_NO=S_NO AND PLANE_NO=P_NO;
IF(COUNTS = 1) THEN
  UPDATE SEAT
  SET RESERVED = ID, BOOKING_TIME = RESERVE_TIME, BOOKED=ID
  WHERE PLANE_NO=P_NO AND SEAT_NO=S_NO;
  COMMIT;
    ELSE IF(COUNTS = 0) THEN
      RES := -1;
    END IF;
  END IF;
  RETURN RES;
END RESERVE_SEAT;

This above function is called by the one below

CREATE OR REPLACE FUNCTION GET_FREE_SEAT(P_NO VARCHAR2, ID NUMBER, RESERVE_TIME NUMBER)
RETURN INTEGER AS
  RESERVED_SEAT_NO VARCHAR2(100) := 'NULL';
  RES INTEGER := 0; -- Assume Success Scenario from the Get-go
BEGIN
  SELECT SEAT_NO INTO RESERVED_SEAT_NO
  FROM SEAT
  WHERE RESERVED IS NULL AND BOOKED IS NULL AND ROWNUM = 1
  OR BOOKED IS NULL AND ((RESERVE_TIME - 5000) <= BOOKING_TIME) AND ROWNUM = 1;

  IF(RESERVED_SEAT_NO != 'NULL') THEN
    RES := RESERVE_SEAT(P_NO,ID,RESERVE_TIME,RESERVEd_SEAT_NO);
  END IF;
  RETURN RES;
END GET_FREE_SEAT;

Not really sure what to do at this point.

How do I return both RES and RESERVED_SEAT_NO ?

Answer

logeekal picture logeekal · May 3, 2014

There is no way you can return 2 variable. It has to be one.

You can use a custom rec type or array which you can return from the function.

TYPE new_type is record(RES pls_integer, RESERVED_SEAT_NO pls_integer);

CREATE OR REPLACE FUNCTION GET_FREE_SEAT(P_NO VARCHAR2, ID NUMBER, RESERVE_TIME NUMBER)
RETURN new_type AS new_type_variable
BEGIN
  SELECT SEAT_NO 
  INTO new_type_variable.RESERVED_SEAT_NO
  FROM SEAT
  WHERE 
      RESERVED IS NULL 
      AND BOOKED IS NULL 
      AND ROWNUM = 1
      OR BOOKED IS NULL 
      AND (RESERVE_TIME - 5000) <= BOOKING_TIME
      AND ROWNUM = 1;

  IF(RESERVED_SEAT_NO != 'NULL') THEN
    select RESERVE_SEAT(P_NO,ID,RESERVE_TIME,RESERVEd_SEAT_NO) into new_type_variable.res from dual;
  END IF;
  RETURN new_type_variable;
END GET_FREE_SEAT;