#oracle #plsql #oracle12c
#Oracle #plsql #oracle12c
Вопрос:
Я пытаюсь создать в памяти массив всех таблиц, содержащих пространственные метаданные и пространственный индекс.
* Я столкнулся с ошибкой,
PLS-00306 неправильное количество аргументов
в приведенном ниже коде в строке:**
v_idx_info_arr(v_array_counter) :=
idx_info_arr('THE_TABLE','THE_OWNER','THE_INDEX_NAME');
Почему это неправильное количество аргументов, когда тип «index_info» имеет 3 поля типа varchar2 (100)?
Я планирую изменить код с этого ^ на idx_info_arr(rec.index_name, rec.table_owner, rec.table_name);
, но для тестирования я оставил его только с жестко закодированными строками.
Я также не уверен в том, как пользовательские типы и массивы работают здесь, в PL / SQL, потому что я собирал их вместе из документации и вопросов о переполнении стека. Любые исправления в этих объявлениях и использовании приветствуются.
DECLARE
TYPE index_info IS RECORD(
table_name varchar2(100),
table_owner varchar2(100),
index_name varchar2(100)
);
CURSOR all_geom_tables IS
SELECT gt.owner, gt.table_name, gt.column_name, gt.srid
FROM all_sdo_geom_metadata gt
WHERE SRID = 8311
ORDER BY TABLE_NAME;
type idx_info_arr is table of index_info;
array v_idx_info_arr := idx_info_arr();
v_array_counter integer := 0;
v_table_geom sdo_geometry;
v_spt_index varchar2(100);
v_view_count integer;
v_index_count integer;
BEGIN
-- Start Loop Through all tables in database
FOR db_table IN all_geom_tables LOOP
-- Loop through all tables which have a spatial index
FOR rec IN (select table_name, table_owner, index_name
from ALL_SDO_INDEX_INFO WHERE
TABLE_OWNER = db_table.owner
AND TABLE_NAME = db_table.table_name) LOOP
DBMS_OUTPUT.PUT_LINE('Index name is: ' || rec.index_name);
-- record the index here
v_idx_info_arr(v_array_counter) := idx_info_arr('THE_TABLE','THE_OWNER','THE_INDEX_NAME');
v_idx_info_arr.extend();
v_array_counter := v_array_counter 1;
END LOOP;
END LOOP;
END;
Ответ №1:
Для версий ниже Oracle 18c вы не можете назначить все элементы записи сразу. Они должны назначаться индивидуально. Кроме того, v_idx_info_arr.extend
требуется перед циклом, так как даже после инициализации без указания элементов коллекция все равно будет иметь нулевой размер.
Код для версий до Oracle 12.2
DECLARE
TYPE index_info IS RECORD ( table_name VARCHAR2(100),
table_owner VARCHAR2(100),
index_name VARCHAR2(100) );
TYPE idx_info_arr IS
TABLE OF index_info;
v_idx_info_arr idx_info_arr := idx_info_arr ();
v_array_counter INTEGER := 1;
BEGIN
v_idx_info_arr.extend;
FOR i IN 1..10 LOOP
v_idx_info_arr(v_array_counter).table_name := 'THE_TABLE';
v_idx_info_arr(v_array_counter).table_owner := 'THE_OWNER';
v_idx_info_arr(v_array_counter).index_name := 'THE_INDEX_NAME';
v_idx_info_arr.extend ();
v_array_counter := v_array_counter 1;
END LOOP;
END;
/
Oracle 18c представила квалифицированные выражения, которые позволяют вам это делать.
v_idx_info_arr(v_array_counter) :=
index_info('THE_TABLE','THE_OWNER','THE_INDEX_NAME');
ДЕМОНСТРАЦИЯ для 18c
Комментарии:
1. Спасибо Kaushik, это решило мою проблему и сделало мой код намного лучше