#sql #oracle #plsql #dynamic-sql #dml
#sql #Oracle #plsql #динамический-sql #dml
Вопрос:
Привет, мне нужно выполнить поиск активности DML в указанном списке таблиц в схеме
один запрос
select max(ora_rowscn),SCN_TO_TIMESTAMP(max(ora_rowscn)) FROM 'TABLE_NAME'
поскольку выполнение отдельных запросов занимает много времени и сложно, я пытаюсь подготовить динамический sql для извлечения max(ora_rowscn), SCN_TO_TIMESTAMP(max(ora_rowscn)) из всех таблиц, чтобы я мог использовать фильтр и выбирать набор таблиц
Шаблон запроса
select 'with tmp(table_name, row_number) as (' from dual
union all
select 'select '''||table_name||''',count(*) from '||table_name||' union ' from USER_TABLES
union all
select 'select '''',0 from dual) select table_name,row_number from tmp order by row_number desc ;' from dual;
как я могу использовать max(ora_rowscn),SCN_TO_TIMESTAMP(max(ora_rowscn)) для всех таблиц
есть предложения по исправлению синтаксиса запроса?
Ответ №1:
Вы можете использовать такой код PLSQL, содержащий EXECUTE IMMEDIATE
для получения желаемых значений с помощью динамического SQL
SET SERVEROUTPUT ON
DECLARE
v_rowscn NUMBER;
v_tmstp TIMESTAMP;
BEGIN
FOR c IN
(SELECT t.table_name FROM user_tables t)
LOOP
BEGIN
EXECUTE IMMEDIATE 'SELECT max(ora_rowscn),SCN_TO_TIMESTAMP(max(ora_rowscn)) FROM '||
c.table_name INTO v_rowscn, v_tmstp;
DBMS_OUTPUT.PUT_LINE( c.table_name||' - max_scn : '|| v_rowscn||
' - max_scn_timestamp : '|| v_tmstp );
EXCEPTION WHEN others THEN DBMS_OUTPUT.PUT_LINE( sqlerrm );
END;
END LOOP;
END;
/
до тех пор, пока не возникнет какое-либо исключение для каждой отдельной таблицы.
Комментарии:
1. Большое спасибо, но если мне нужно фильтровать по схеме и списку таблиц?
2. Я не знаю вашего правила фильтрации, но просто замените запрос, добавив условие WHERE, например,
... WHERE table_name LIKE 'R%'
для того, чтобы только таблицы начинались с буквыR
@rakesh3. для тестирования я отфильтровал по схеме, а также по таблице анонимный блок завершен, но как просмотреть результаты?
4. Вы выполняли проблему
SET SERVEROUTPUT ON
перед вызовомDBMS_OUTPUT.PUT_LINE
@rakesh?5. упс, я забыл указать, что это работает сейчас, один вопрос, как получить значение метки времени?
Ответ №2:
Вот мое предложение. Я бы не рекомендовал использовать SCN_TO_TIMESTAMP
для всех таблиц, так как это приведет к частому выбросу ORA-01405.
select 'with tmp(table_name, max_rscn, ct) as (' from dual
union all
select 'select '''||table_name||''',max(ora_rowscn), count(*) from '||table_name||' union ' from USER_TABLES
union all
select 'select '''',0,0 from dual) select table_name, max_rscn from tmp;' from dual;
Комментарии:
1. @Kinfinity мне нужно извлечь данные из обоих этих двух столбцов max(ora_rowscn),SCN_TO_TIMESTAMP(max(ora_rowscn)) для выбранных таблиц