#sql #oracle #plsql
#sql #Oracle #plsql
Вопрос:
Я написал простой скрипт, который немедленно уничтожит сеанс oracle:
DECLARE
v_kill VARCHAR2(32767);
BEGIN
FOR v_kill IN
(SELECT
'alter system kill session '''
||sid
||','
||serial#
||'''',
'immediate;'
FROM
v$session
WHERE
sql_id='sql_id_here'
)
LOOP
EXECUTE immediate v_kill;
END LOOP;
END;
К сожалению, я получаю сообщение об ошибке, из-за которого я застрял в этой проблеме:
Error report -
ORA-06550: linia 18, kolumna 21:
PLS-00382: expression is of wrong type
ORA-06550: linia 18, kolumna 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Любая помощь будет оценена!
Ответ №1:
Чтобы использовать курсор таким образом, вам нужно присвоить al alias столбцу инструкции и выполнить это:
BEGIN
FOR v_kill IN
(SELECT
'alter system kill session '''
||sid
||','
||serial#
|| ''' immediate;' as statement
FROM
v$session
WHERE
sql_id='sql_id_here'
)
LOOP
dbms_output.put_line (v_kill.statement);
END LOOP;
END;
Кроме того, вам не нужно объявлять переменную для обработки курсора.
Комментарии:
1. Ошибка, скорее всего, сохранится при этом, потому что на самом деле этот запрос возвращает два столбца. Вы присвоили псевдоним второму столбцу (содержит ‘immediate’) в качестве оператора, и это не будет выполняться очень хорошо. Строка ‘immediate’ должна быть объединена с остальной частью команды, чтобы вернуть полную команду в одном столбце.
2. Вы абсолютно правы. Я не заметил ошибки и скопировал ее в своем ответе.
Ответ №2:
Алексей абсолютно прав насчет синтаксиса.
Также имейте в виду, что этот запрос уничтожит сеансы только в текущем экземпляре, если вы запустите это в RAC. Если вам нужно быть абсолютно уверенным, что вы уничтожите все сеансы во всех экземплярах с вашим sql_id, вам нужно использовать gv $ session view и идентификатор сеанса в форме ‘sid, serial #, @inst_id’.
Ответ №3:
SELECT 'alter system kill session ''' ||sid ||','||serial# ||',@'||inst_id||''';' from gv$session where sql_id = 'amp;sql_id'