Переменные связывания в вашем выражении обрабатываются как буквенные строки, а не как заполнители. Если вы выводите оператор, который вы генерируете:
BEGIN
FOR REC IN (SELECT sid,serial# serial FROM V$SESSION WHERE username = user)
LOOP
dbms_output.put_line('alter system kill session '':1,:2'' immediate');
END LOOP;
END;
/
... вы видите строки вроде:
alter system kill session ':1,:2' immediate
':1,:2'
обрабатывается как статическое значение, а не как две переменные связывания. Вы не можете использовать переменные связывания в динамическом DDL, и я не уверен, применимо ли это к alter
командам, так что в любом случае это может быть невозможно.
Простейшим способом достижения этого может быть генерация всего оператора в курсоре:
BEGIN
FOR REC IN (
SELECT 'alter system kill session ''' || sid ||','|| serial#
||''' immediate' stmt
FROM V$SESSION WHERE username = user)
LOOP
dbms_output.put_line(rec.stmt);
--execute immediate rec.stmt;
END LOOP;
END;
/
С комментарием execute
(я не хочу сейчас убивать мои сеансы), вы можете просто увидеть команды, которые он будет выполнять, например:
alter system kill session '58,47157' immediate
Ваш подход все еще может быть ошибочным, поскольку он убьет сеанс, выполняющий блок, и может завершить или не завершить его в последний раз. Я думаю, что это в сферах неопределенного поведения, и я действительно не хочу пробовать это, чтобы выяснить, что происходит ... Я сомневаюсь, что это то, что вы на самом деле хотите в любом случае.
Редактировать: «некорректный» комментарий был основан на использовании user
, который в моем анонимном блоке был бы исполняющим пользователем; в вашем процессе это будет пользователь из параметра. Однако использование ключевого слова в качестве имени параметра сбивает с толку, поэтому я рекомендую изменить имя на что-то вроде p_user
в аргументах и в выражении.