How to return a record from an existing table from an Oracle PL/SQL function?

前端 未结 1 1599
自闭症患者
自闭症患者 2020-12-30 13:07

I know it seems like a basic thing, but I\'ve never done this before.

I\'d like to return a single record from an existing table as the result of an Oracle PL/SQL fu

相关标签:
1条回答
  • 2020-12-30 13:35

    This is how I would do it. Variables/table-names/column-names are case-insensitive in Oracle, so I would use user_name instead of UserName.

    CREATE TABLE users( UserName varchar2(20), OtherStuff VARCHAR2(20) );
    

    Function update_and_get_user. Note that I return a ROWTYPE instead of Pipelined Tables.

    CREATE OR REPLACE FUNCTION update_and_get_user(
      in_UserName   IN users.UserName%TYPE,
      in_OtherStuff IN users.OtherStuff%TYPE )
    RETURN users%ROWTYPE
    IS
      output_rec users%ROWTYPE;
    BEGIN
      UPDATE users
      SET OtherStuff = in_OtherStuff
      WHERE UserName = in_UserName
        RETURNING UserName, OtherStuff
        INTO output_rec;
      RETURN output_rec;
    END update_and_get_user;
    

    And this is how you would call it. You can not check a ROWTYPE to be NULL, but you can check username for example.

    DECLARE
      users_rec users%ROWTYPE;
    BEGIN
      users_rec := update_and_get_user('user', 'stuff');
      IF( users_rec.username IS NOT NULL ) THEN
        dbms_output.put_line('FOUND: ' || users_rec.otherstuff);
      END IF;
    END;
    

    A solution using PIPED ROWS is below, but it doesn't work that way. You can not update tables inside a query.

    SELECT * FROM TABLE(update_and_get_user('user', 'stuff'))
    
    ORA-14551: cannot perform a DML operation inside a query
    

    Solution would look like that:

    CREATE OR REPLACE TYPE users_type
    AS OBJECT
    (
      username   VARCHAR2(20),
      otherstuff VARCHAR2(20)
    )
    
    CREATE OR REPLACE TYPE users_tab
       AS TABLE OF users_type;
    
    CREATE OR REPLACE FUNCTION update_and_get_user(
      in_UserName   IN users.username%TYPE,
      in_OtherStuff IN users.otherstuff%TYPE )
    RETURN users_tab PIPELINED
    IS
      output_rec users%ROWTYPE;
    BEGIN
      UPDATE users
      SET OtherStuff = in_OtherStuff
      WHERE UserName = in_UserName
        RETURNING username, otherstuff
        INTO output_rec;
      PIPE ROW(users_type(output_rec.username, output_rec.otherstuff));
    END;
    
    0 讨论(0)
提交回复
热议问题