Oracle: установка параметров сеанса в пакетах и ​​процедурах - PullRequest
3 голосов
/ 24 января 2020

Я SQL Серверный администратор базы данных, в настоящее время набирающий скорость на Oracle Я пытаюсь создать что-то очень похожее на sp_WhoIsActive для SQL Server, но для Oracle, не изобретая велосипед. По сути, все, что я делаю, - это выбираю некоторые значения из v $ session и вставляю их в таблицу (ASH / AWR бедняка).

Может показаться, что в Oracle 12.1 существует ошибка при запросе представлений словаря, где он может длиться вечно из-за плохого анализа паролей c (Ошибка 22225899: МЕДЛЕННЫЙ РАЗДЕЛ ДЛЯ СЛОЖНОГО ЗАПРОСА). Обходной путь - установить параметр сеанса:

alter session set "_optimizer_squ_bottomup"=false;

В T- SQL я мог бы очень легко выполнить хранимую процедуру в сеансе и установить эту переменную во время выполнения , Однако в Oracle это не выглядит так.

Пример кода:

CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(
    v_temp NUMBER :=1
) IS
BEGIN
alter session set "_optimizer_squ_bottomup"=false;
INSERT INTO SY_DB_ACTIVITY 
    SELECT  
       <fields>
    FROM
      v$session;
commit;

Когда я запускаю это, я получаю ошибку:

"PLS-00103: Обнаружен символ« ALTER »при ожидании одного из следующих ...»

Прямо сейчас, единственный способ, которым я знаю, как это сделать, - это утилита, подобная SQL Плюс, который инициирует интерактивный сеанс пользователя. Кто-нибудь может дать мне какое-то указание о том, как Oracle справляется с этой ситуацией? Я хотел бы связать это в SP или Package и затем вызвать его из Oracle Scheduler.

1 Ответ

4 голосов
/ 25 января 2020

Вот простой пример того, как выполнить alter session внутри процедуры:

CREATE PROCEDURE SP_DB_ACTIVITY IS
BEGIN

EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';

END;
/

Вот способ, которым вы можете объединить это с вашим оператором выбора и вставки:

CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS 

    v_Id NUMBER;
BEGIN
    EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';

    SELECT 1 
    INTO v_Id
    FROM dual;

    INSERT INTO SY_DB_ACTIVITY (id) VALUES(v_Id); 
 END SP_DB_ACTIVITY; 
 /

Вот небольшая ДЕМО , где вы можете увидеть, что будет делать процедура, когда вы ее вызываете, и как вы можете ее вызвать. Также в этом примере вы вызываете процедуру с параметром IN. Таким образом, вы можете использовать этот параметр для чего-то, и в приведенном выше примере это процедура без каких-либо параметров ...

Вы также можете, конечно, напрямую вставить в таблицу:

CREATE OR REPLACE PROCEDURE SP_DB_ACTIVITY
(v_temp IN number) AS 

    v_Id NUMBER;
BEGIN
    EXECUTE IMMEDIATE 'alter session set "_optimizer_squ_bottomup"=false';

    INSERT INTO SY_DB_ACTIVITY(id) 
    select 1
    from dual; 

 END SP_DB_ACTIVITY; 
 /
...