Oracle Stored Procedure Return Recordset with Fiel

2019-09-01 16:47发布

问题:

I am new to Oracle and Stored Procedures. I just would like to know if its possible, like in SQL Server, to return a recordset with Field Names to an extern program. I read some documentations but I'm not sure if I'm on the right track. When I use Sys_Refcursor I can only return one Field and not as many as I would like to.

I need to return multiple Field Names and I have one input parameter.

In the documentation of the program, i have an example for SQL Server and I would like to have the same for my Oracle Stored Procedure:

Use
Go
Set Ansi_Nulls ON
Go
Alter Procedure
   @InputLocation Varchar(255)
As
Begin
   Set Nocount On;
   select FirstName as '@FirstName', Company as '@Company' from dbo.company where Location = @InputLocation
End

Are there any suggestions how I can do that? If you need some additional informations just let me know. Thanks.

/edit:

My sample Code (without using the Input Parameter in the first step, just for generating Output to see if it works):

create or replace 
PROCEDURE TEST_PROZEDUR1 (
  Input_Location IN Varchar2, 
  First_Name OUT SYS_Refcursor, 
  Company OUT Sys_Refcursor) IS 
BEGIN
  open First_Name For Select FirstName from dbo.company;
  open Company For Select Company from dbo.company;
END TEST_PROZEDUR1;

回答1:

The programming models used for PL/SQL and TSQL are different. Where you might return a recordset in TSQL, in PL/SQL you would return a cursor. A cursor is just a pointer to an SQL statement which is opened and can be read. It is not limited to returning a single column. Roughly, the PL/SQL equivalent of your TSQL procedure above would be something like:

CREATE OR REPLACE FUNCTION GET_INPUT_LOCATION(pinInput_location IN VARCHAR2(255))
  RETURN SYS_REFCURSOR
IS
  cCursor  SYS_REFCURSOR;
BEGIN
  OPEN cCursor FOR
    SELECT FIRSTNAME,
           COMPANY
      FROM COMPANY
      WHERE LOCATION = pinInput_location;

  RETURN cCursor;
END GET_INPUT_LOCATION;

The caller would then invoke this function as:

DECLARE
  cCursor       SYS_REFCURSOR;
  strFirstname  COMPANY.FIRSTNAME%TYPE;
  strCompany    COMPANY.COMPANY%TYPE;
BEGIN
  cCursor := GET_INPUT_LOCATION('SOMEWHERE OVER THE RAINBOW, INC.');

  FETCH cCursor
    INTO strFirstname,
         strCompany;

  CLOSE cCursor;
END;

However, I probably wouldn't code it this way. If COMPANY.LOCATION is unique then you're going to a lot of trouble to return a cursor which the caller will need to remember to close when they're done with it, which they may forget to do. Instead, I'd just return the FIRSTNAME and COMPANY fields using output parameters; e.g.

CREATE OR REPLACE PROCEDURE GET_INPUT_LOCATION
  (pinInput_location IN  VARCHAR2(255),
   poutFirst_name    OUT COMPANY.FIRSTNAME%TYPE,
   poutCompany       OUT COMPANY.COMPANY%TYPE)
IS
  cCursor  SYS_REFCURSOR;
BEGIN
  SELECT FIRSTNAME,
         COMPANY
    INTO poutFirst_name,
         poutCompany
    FROM COMPANY
    WHERE LOCATION = pinInput_location;
END GET_INPUT_LOCATION;

Share and enjoy.