Обнаруженная ошибка Не удается получить доступ к строкам из невложенного элемента таблицы при использовании varrays в хранимой процедуре plsql

Я новичок в plsql и пытаюсь написать процедуру, которая подсчитывает количество записей в таблице и помещает результат в другую таблицу. Теперь есть несколько таблиц, для которых я хочу сделать это, поэтому я помещаю их в varray, но сталкиваюсь с вышеупомянутой ошибкой.

Create Or Replace Procedure count
AS
type arr IS VARRAY(5) OF VARCHAR2(30);
tables arr :=arr('tb1','tb2','tb3','tb4','tb5');
cnt NUMBER;
BEGIN
   FOR i in 1 .. tables.COUNT
   LOOP
    select Count(*) INTO cnt from tables(i);
    insert into tb6 VALUES(tables(i),cnt);
    END LOOP
END;

У вас есть VAUES не VALUES., END LOOP отсутствует разделитель оператора ;. Кроме того, COUNT — это встроенная функция, и вы должны называть ее по-другому.

MT0 08.04.2022 13:52

Это была просто опечатка

My thoughts 08.04.2022 13:54
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
2
22
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Для этого вам понадобится динамический SQL.

Вот как: несколько примеров таблиц (на основе таблицы emp Скотта) и tb6, которые будут содержать результат:

SQL> create table tb6 (val varchar2(10), cnt number);

Table created.

SQL> create table tb1 as select * from emp where deptno = 10;

Table created.

SQL> create table tb2 as select * from emp where deptno = 20;

Table created.

SQL> create table tb3 as select * from emp where deptno = 30;

Table created.

Какой результат я ожидаю?

SQL> select deptno, count(*) from emp group by deptno order by deptno;

    DEPTNO   COUNT(*)
---------- ----------
        10          3
        20          5
        30          6

Процедура:

SQL> create or replace procedure p_count as
  2    type   arr is varray(5) of varchar2(30);
  3    tables arr := arr('tb1', 'tb2', 'tb3');
  4    cnt    number;
  5  begin
  6     for i in 1 .. tables.count loop
  7       execute immediate 'select count(*) from ' || tables(i) into cnt;
  8       insert into tb6 values(tables(i), cnt);
  9     end loop;
 10  end;
 11  /

Procedure created.

Тестирование:

SQL> set serveroutput on
SQL> exec p_count;

PL/SQL procedure successfully completed.

SQL> select * from tb6;

VAL               CNT
---------- ----------
tb1                 3
tb2                 5
tb3                 6

SQL>

Как видите, содержимое tb6 соответствует ожидаемым значениям.

Спасибо за помощь, просто хотел спросить, целесообразно ли использовать динамический sql, так как это приведет к огромному снижению производительности?

My thoughts 09.04.2022 09:51

Пожалуйста. Что касается динамического SQL: используйте его, если необходимо. Вы могли бы сделать то же самое, используя несколько отдельных запросов, поэтому... вам решать, по какому пути вы пойдете. Для таких простых динамических операторов я бы сказал, что это более простой подход, который легко поддерживать. Для сложных динамических операторов, которые сложно писать, отлаживать и поддерживать, стоит подумать о другом подходе.

Littlefoot 09.04.2022 10:14

Да, именно это кажется более простым подходом, потому что я только тестировал это на самом деле. У меня есть более 50 таблиц, для которых мне нужно это сделать, так что это означало бы написание аналогичных sql-запросов более 50 раз, если используется статический sql.

My thoughts 09.04.2022 10:36

Другие вопросы по теме