Создание функции, которая возвращает таблицу, которая еще не объявлена - PullRequest
0 голосов
/ 30 мая 2018

Наш продукт имеет несколько компонентов, которые могут быть установлены отдельно, и поддерживает oracle.Но мы не предоставляем Create type привилегии.Поэтому во время установки одного из компонентов мне нужно попросить клиента установить компонент, добавить привилегию Create type и затем запустить мой компонент.

В файле SQL, который будет создавать функции, которые я планировал дать следующимкод:

CREATE OR REPLACE FUNCTION get_some_data (input INT)
    RETURN my_table
AS
    my_table_var   my_table := my_table ();
    ret_code       INT := 0;
BEGIN
    ret_code := create_my_type_and_table ();

    IF 1 = ret_code
    THEN
        NULL; -- add some data to my_table_var here
    END IF;

    RETURN my_table_var;
END get_some_data;
/

Функция create_my_type_and_table будет использовать execute immediate для создания записи и типа таблицы.

Очевидно, проблема в том, что функция get_some_data говорит, что вернет my_table, компиляция не удалась.

Я хотел знать:

  • есть ли выход?

  • причина, по которой яхочу создать и вернуть таблицу, потому что мне нужно вернуть несколько полей.Все они инт.Есть ли способ вернуть многомерный массив, возможно, системную коллекцию?Я попытался использовать sys.odcinumberlist, но не нашел способа вернуть 4-колонный sys.odcinumberlist.

1 Ответ

0 голосов
/ 30 мая 2018

Если вам нужны анонимные общие элементы, вы можете использовать TABLE OF [TYPE].

Вот пример того, как создать table of number, который используется другим типом "table of table of number".

Как и каждый тип, вы можете создавать их в своей схеме, чтобы использовать их между различными блоками plsql или возвращаемым значением в функциях.

declare
    TYPE tableOfNumber is Table of Number; -- Define a row of numbers
    TYPE tableOfTableOfNumer is Table of tableOfNumber; -- define a table of rows

    tableMaster tableOfTableOfNumer := tableOfTableOfNumer(); -- init tables
    tableChild1 tableOfNumber := tableOfNumber();
    tableChild2 tableOfNumber := tableOfNumber();
begin
    tableChild1.Extend; -- add a new number-field to our table 
    tableChild1(1) := 0; -- set the value to the new field
    tableChild1.Extend;
    tableChild1(2) := 1;
    tableChild2.Extend;
    tableChild2(1) := 2;
    tableChild2.Extend;
    tableChild2(2) := 3;
    tableMaster.Extend; -- add a new 'row' to out table
    tableMaster(1) := tableChild1; -- fill the new 'row' with the fields
    tableMaster.Extend;
    tableMaster(2) := tableChild2;

    -- loop through our 'table'
    for r in 1 .. tableMaster.Count
    LOOP
        for c in 1 .. tableMaster(r).Count
        LOOP
            dbms_output.put_line(tableMaster(r)(c)); 
        END LOOP;
    END LOOP;
end;

Если вы хотите создать функцию, вам необходимо:

1.Объявите типы в вашей схеме

(предоставьте права пользователям)

CREATE TYPE tableOfNumber AS TABLE OF NUMBER;
CREATE TYPE tableOftableOfNumber AS TABLE OF tableOfNumber;

2.Создайте свою функцию:

(здесь с тем же кодом, что и у блока plsql)

CREATE OR REPLACE FUNCTION DINTER.MyFunction
RETURN tableOftableOfNumber
Is
    tableMaster tableOftableOfNumber := tableOftableOfNumber(); -- init tables
    tableChild1 tableOfNumber := tableOfNumber();
    tableChild2 tableOfNumber := tableOfNumber();
begin
    tableChild1.Extend; -- add a new number-field to our table 
    tableChild1(1) := 0; -- set the value to the new field
    tableChild1.Extend;
    tableChild1(2) := 1;
    tableChild2.Extend;
    tableChild2(1) := 2;
    tableChild2.Extend;
    tableChild2(2) := 3;
    tableMaster.Extend; -- add a new 'row' to out table
    tableMaster(1) := tableChild1; -- fill the new 'row' with the fields
    tableMaster.Extend;
    tableMaster(2) := tableChild2;

    RETURN tableMaster;

end MyFunction;
/

3.Вызовите функцию:

declare
    tableMaster tableOfTableOfNumber;
begin
    tableMaster := myfunction();
    -- loop through our 'table'
    for r in 1 .. tableMaster.Count
    LOOP
        for c in 1 .. tableMaster(r).Count
        LOOP
            dbms_output.put_line(tableMaster(r)(c)); 
        END LOOP;
    END LOOP;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...